Anzeige:
Ergebnis 1 bis 12 von 12

Thema: typedef std::list<boost::any> many; - Beispiel

  1. #1
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54

    Question typedef std::list<boost::any> many; - Beispiel

    Folgende Frage.

    habe von der Boost.org Seite das Beispiel

    Code:
    #include <list>
    #include <boost/any.hpp>
    
    using boost::any_cast;
    typedef std::list<boost::any> many;
    
    void append_int(many & values, int value)
    {
        boost::any to_append = value;
        values.push_back(to_append);
    }
    
    void append_string(many & values, const std::string & value)
    {
        values.push_back(value);
    }
    
    void append_char_ptr(many & values, const char * value)
    {
        values.push_back(value);
    }
    
    void append_any(many & values, const boost::any & value)
    {
        values.push_back(value);
    }
    
    void append_nothing(many & values)
    {
        values.push_back(boost::any());
    }
    
    bool is_empty(const boost::any & operand)
    {
        return operand.empty();
    }
    
    bool is_int(const boost::any & operand)
    {
        return operand.type() == typeid(int);
    }
    
    bool is_char_ptr(const boost::any & operand)
    {
        try
        {
            any_cast<const char *>(operand);
            return true;
        }
        catch(const boost::bad_any_cast &)
        {
            return false;
        }
    }
    
    bool is_string(const boost::any & operand)
    {
        return any_cast<std::string>(&operand);
    }
    
    void count_all(many & values, std::ostream & out)
    {
        out << "#empty == "
            << std::count_if(values.begin(), values.end(), is_empty) << std::endl;
        out << "#int == "
            << std::count_if(values.begin(), values.end(), is_int) << std::endl;
        out << "#const char * == "
            << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;
        out << "#string == "
            << std::count_if(values.begin(), values.end(), is_string) << std::endl;
    }
    kopiert...
    nachdem ich oben noch zwei Zusätzliche Includes gemacht habe kompiliert er es jetzt auch...

    nun die Frage...
    ich wollte nun mit der Funktion

    Code:
    append_any(many & values, const boost::any & value)
    einen beliebigen Wert hinzufügen...

    nur hab ich keinen plan wie der Aufruf der Funktion sein soll

    desweiteren

    wo ist dieser

    values -Wert zu finden??
    wird dieser nur durch den Aufruf der Funktion erzeugt??

    kann mir jemand einen Beispielaufruf einer Funktion zeigen, mit dem ein Wert zugewiesen wird?

    merci UFOSWORLD

    p.s. für was brauche ich diesen Code
    Code:
     struct property
    {
        property();
        property(const std::string &, const boost::any &);
    
        std::string name;
        boost::any value;
    };
    
    typedef std::list<property> properties;

    Code:
    class consumer
    {
    public:
        virtual void notify(const any &) = 0;
        ...
    };

  2. #2
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54

    Question

    folgenden Code wollte ich testhalber mal Boost::any tauglich machen... klappt aber nicht..



    Code:
    #include <string>
    #include <iostream>
    #include <list>
    #include <boost/any.hpp>
    #include <stdio.h>
    
    typedef std::list<int> Listera; //creating a list
    //typedef std::list<boost::any> intList; //creating a list
    
    int main()
    {
    
    
        Listera  intList;
    
        for(int i=1; i<=6; i++) intList.push_back(i);
    
    
        std::list<int>::iterator it; //modyfing list
        //std::list<boost::any>::iterator it; //modyfing list
    
        for(it = intList.begin(); it != intList.end(); it++)
        {
          if(*it == 3) //deleting an element in the middle
            {
              intList.erase(it);
              it--;
            }
    
    
        }
    
                                       //showing list
        for(it = intList.begin(); it != intList.end(); it++)
            printf("value = %d\n", *it);
    	//Ausgabe für boost::any = ???
    
    
        return 0;
    }
    hat jemand hilfreiche Tips wie ich den Code so umschreibe, das er statt int Variablen, jeden Wert speichern und ausgeben kann?
    also nicht nur die Zahlen 1-6 sondern z.b. auch Texte

  3. #3
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Dem Boost Beispiel zu Folge braucht man für "int" einen Zwischenschritt.

    Probier statt direktem push_back die Funktion append_int() aus dem Beispiel, also
    Code:
    for(int i=1; i<=6; i++) append_int(intList, i);
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  4. #4
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54

    Angry Fragen über Fragen

    ok irgendwie hat das nicht geklappt... habe aber jetzt folgenden Code zum laufen gebracht...

    Code:
    #include <string>
    #include <iostream>
    #include <list>
    #include <boost/any.hpp>
    #include <stdio.h>
    
    using boost::any_cast;
    typedef std::list<boost::any> many;
    
    /*
    struct property
    {
        property();
        property(const std::string &, const boost::any &);
    
        std::string name;
        boost::any value;
    };
    
    typedef std::list<property> properties;
    */
    
    
    // append_xxxx
    
    void append_int(many & values, int value)
    {
        boost::any to_append = value;
        values.push_back(to_append);
    }
    
    void append_string(many & values, const std::string & value)
    {
        values.push_back(value);
    }
    
    void append_char_ptr(many & values, const char * value)
    {
        values.push_back(value);
    }
    
    void append_any(many & values, const boost::any & value)
    {
        values.push_back(value);
    }
    
    void append_nothing(many & values)
    {
        values.push_back(boost::any());
    }
    
    /// IS_xxxxx
    
    
    bool is_empty(const boost::any & operand)
    {
        return operand.empty();
    }
    
    bool is_int(const boost::any & operand)
    {
        return operand.type() == typeid(int);
    }
    
    bool is_char_ptr(const boost::any & operand)
    {
        try
        {
            any_cast<const char *>(operand);
            return true;
        }
        catch(const boost::bad_any_cast &)
        {
            return false;
        }
    }
    
    bool is_string(const boost::any & operand)
    {
        return any_cast<std::string>(&operand);
    }
    
    
    //  count_all
    
    void count_all(many & values, std::ostream & out)
    {
        out << "#empty == "
            << std::count_if(values.begin(), values.end(), is_empty) << std::endl;
        out << "#int == "
            << std::count_if(values.begin(), values.end(), is_int) << std::endl;
        out << "#const char * == "
            << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;
        out << "#string == "
            << std::count_if(values.begin(), values.end(), is_string) << std::endl;
    }
    
    int main()
    {
    
      many values;
    
      append_int(values,3);
      append_int(values,1);
      append_int(values,4);
      append_int(values,5);
      append_int(values,6);
      append_int(values,8856);
    
      append_any(values,23223);
    
    
      append_string(values,"test");
      append_string(values,"asa");
      append_string(values,"tast");
      append_string(values,"sd");
      append_string(values,"ddsdt");
    
      append_any(values,"tste");  //wird irgendwie nicht mitgezählt
    
      std::cout << std::count_if(values.begin(), values.end(), is_int)<<std::endl;  // 7
      std::cout << std::count_if(values.begin(), values.end(), is_string)<<std::endl; // 5
    
     return 0;
    }
    wie es scheint speichert er die werte jeweils in values ab...
    mitm Zählen happert es etwas... woran kann das liegen??

    die Int Werte zählt er richtig, aber die String Werte nicht...
    registriert der die
    Code:
    append_any(values,"tste");
    nicht als string??
    wieso macht er es dann bei der Zeile

    Code:
    append_any(values,23223);
    ???

    nun wollte ich die gesammte Liste auf der Console ausgeben...
    nur habe ich keinen Plan wie das geht...
    hat jemand entsprechenden Code dafür??
    gibt es sowas wie count_if auch für die Ausgabe??
    wo ist dieses count_if definiert???
    in Boost??
    finde leider in der Boost Hilfe nichts zu dem count_if
    und in den man Pages auch nicht...

    wie kann ich auf einzelne Elemente zugreifen in der Liste??

    benötige ich dafür wieder einen Iterator??
    wenn ja, wie erzeuge ich den für list<boost::any> ??
    und wie sieht dann der code zur ausgabe der Liste aus??


    merci schon mal

    ufosworld

  5. #5
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von ufosworld Beitrag anzeigen
    wie es scheint speichert er die werte jeweils in values ab...
    mitm Zählen happert es etwas... woran kann das liegen??

    die Int Werte zählt er richtig, aber die String Werte nicht...
    Doch, tut er. Du hast 5 Stringwerte, 7 Intwerte und einen Charpointerwert.

    registriert der die
    Code:
    append_any(values,"tste");
    nicht als string??
    Nein, "tste" ist ein "const char*", kein std::string

    wieso macht er es dann bei der Zeile

    Code:
    append_any(values,23223);
    ???
    Es gibt eine implizite Konversion von int nach any.
    Das trifft auch für den "const char*" zu, daher muss der Compiler den "const char*" nicht erst in einen std::string umwandeln, bevor er das any Object erzeugt.

    Das hier sollte dein gewünschtes Ergebnis erzielen:
    Code:
    append_any(values,string("tste"));
    gibt es sowas wie count_if auch für die Ausgabe??
    Es gibt einen Standard "Copy" Algorithmus, der auf Iteratoren angewendet werden kann und einen Möglichkeit, einen Zielinterator auf einem Outputstream zu erzeugen (allerdings weiß ich das nicht auswendig)

    wo ist dieses count_if definiert???
    in Boost??
    Nein, das gehört zur C++ Standard Template Library STL, Header <algorithm> wenn ich nicht irre.

    wie kann ich auf einzelne Elemente zugreifen in der Liste??

    benötige ich dafür wieder einen Iterator??
    Iterator oder Indexoperator des Containers.
    Im Falle einer Liste ist der Iterator performanter

    wenn ja, wie erzeuge ich den für list<boost::any> ??
    In C++ geht das ziemlich generell so:
    Code:
    IteratorTyp variable = container.begin();
    also in deinem Fall zB
    Code:
    std::list<boost::any>::iterator it = values.begin();
    bzw. da du ein typedef hast
    Code:
    many::iterator it = values.begin();
    Eine Schleife mit einem Iterator kann man so machen
    Code:
    many::iterator it       = values.begin();
    many::iterator endIt = values.end();
    for (; it != endIt; ++it)
    {
    }
    Bzw., falls man nichts ändern möchte, oder nicht kann, weil der Container eine const Reference ist
    Code:
    many::const_iterator it       = values.begin();
    many::const_iterator endIt = values.end();
    for (; it != endIt; ++it)
    {
    }
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  6. #6
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54
    Code:
    many::iterator it       = values.begin();
    many::iterator endIt = values.end();
    for (; it != endIt; ++it)
    {
    }
    ahja... und was müsste ich in die klammern schreiben??

    std::cout << (*it) <<endl;

    ???

  7. #7
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54

    Question

    also


    Code:
    std::cout << (*it) <<endl;
    ist es nicht (Tausende von Fehlermeldungen)

    Code:
    std::cout << (it) <<endl;
    ist es auch nicht

    Code:
    std::cout << values.it) <<endl;
    auch nicht

    bei
    Code:
    std::cout << (&it) <<endl;
    haut er mir 13 mal die Adresse raus, in der it gespeichert ist...

    wie schaffe ich es es die gespeicherten Werte auszugeben??

    merci UFO

  8. #8
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Code:
    *it
    dereferenziert erstmal nur den Iterator, d.h. du hast dann dort eine Instanz von any

    An den Inhalt eine Any kommt man mit any_cast
    Beispiel:
    Code:
    if (is_int(*it))
        cout << any_cast<int>(*it);
    else if (is_string(*it))
        cout << any_cast<string>(*it);
    else if (is_char_ptr(*it))
        cout << any_cast<const char*>(*it);
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  9. #9
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54

    Smile

    Ok das geht soweit...
    nun wollte ich in der Liste gespeicherte Werte verändern/tauschen

    hab da den Befehl swap bei List gefunden

    aber wie der Code hier aussieht kann man mit dem Swap Befehl nur ganze Listen tauschen

    Code:
    // swap lists
    #include <iostream>
    #include <list>
    using namespace std;
    
    main ()
    {
      list<int> first (3,100);   // three ints with a value of 100
      list<int> second (5,200);  // five ints with a value of 200
      list<int>::iterator it;
    
      first.swap(second);
    
      cout << "first contains:";
      for (it=first.begin(); it!=first.end(); it++) cout << " " << *it;
    
      cout << "\nsecond contains:";
      for (it=second.begin(); it!=second.end(); it++) cout << " " << *it;
    
      cout << endl;
    
      return 0;
    }
    gibt es auch eine Funktion mit der ich direkt auf die Elemente der liste zugreifen und diese verändern kann.

    Will folgendes machen können.
    - Werte tauschen innerhalb der Liste
    - Werte verändern
    - Werte in neuer Liste an andere Position schreiben


    gruss UFO

  10. #10
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54
    ok habs mittlerweile rausgefunden

    mit iter_swap kann man Elemente tauschen

    nur hab ich nun folgendes Problem:

    Boost::Any hat ja den Vorteil das man da erstmal alles reinpacken kann...
    er identifiziert das dann entsprechend...

    jetzt wollte ich ein String Element am Anfang mit einem IntegerWert am Ende tauschen.... aber da bringt er wieder nur ABBRUCH.

    auch habe ich probiert die Werte jeweils im Datentyp Any zu speichern,
    nur er wandelt z.b.

    append_any(values,"Test"); intern in einen Char_Ptr um
    und
    append_any(values,12345); intern in einen Integer Wert um
    und
    append_string(values,"Test"); ist von der definition her schon ein String Wert.


    stösst hier iter_swap an seine Grenzen und gibt es eine Möglichkeit diese Werte trotzdem zu tauschen? Anscheinend kann iter_swap nur Werte gleichen Datentyps tauschen....

    desweiteren nervt etwas, das man nicht it = it+5; machen kann
    sondern 5 mal it++; machen muss , wenn man auf das 6te Element navigieren möchte... um dieses z.b. zu removen...

    merci schon mal

  11. #11
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Ansich sollte im allgemeinen Fall immer das hier funktionieren

    Code:
    boost::any value = *it1;
    *it1 = *it2;
    *it2 = value;
    bzw mit std::swap

    Aber wenn es einen Iterator Swap gibt (war mir bisher gar nicht bekannt), dann sollte der schon auch gehen, der Typ des Containers ist ja immer boost::any

    Einen Wert ändern geht ungefähr so

    Code:
    boost::any newvalue = string("Foo");
    many::iterator it = values.begin();
    *it = newvalue;
    Bzw mit Methoden der Containerklasse.

    Zum Teilproblem it + 5:
    Code:
    it += 5;
    sollte gehen.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  12. #12
    Registrierter Benutzer
    Registriert seit
    11.04.2007
    Beiträge
    54

    Wink

    also mit dem std::swap befehl,
    kann man nur immer alle Werte von zwei Objekten tauschen...
    siehe hier:
    http://www.cplusplus.com/reference/algorithm/swap.html

    das iter_swap ist kein Iterator Namens Swap sondern
    eine Funktion die so heisst..
    siehe hier:
    http://www.cplusplus.com/reference/a...iter_swap.html

    Sie tauscht Werte auf die jeweils der Iterator zeigt... das geht auch innerhalb eines Objektes...


    Die Funktion append_any ist bei mit so:

    Code:
    void append_any(many & values, const boost::any & value)
    {
        values.push_back(value);
    }
    Aber irgendwie wandelt der das dann intern ( wie mir schein in dem Boost Zeugs auf Integer oder Char_Ptr... je nachdem ob Zeichenkette oder Zahlen als Value angegeben wurden....
    jedenfalls bringt er bei dem Befehl count_if
    wenn ich einmal append_any mit "Testtext" und einmal mit 12345 mache
    Integer = 1
    Char_Ptr = 1
    String = 0
    Nothing = 0

    (als beispiel diese Funktion... die nicht ganz läuft... aber das wichtigste is drin..

    Code:
    void count_all(many & values, std::ostream & out)
    {
        out << "#empty == "
            << std::count_if(values.begin(), values.end(), is_empty) << std::endl;
        out << "#int == "
            << std::count_if(values.begin(), values.end(), is_int) << std::endl;
        out << "#const char * == "
            << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;
        out << "#string == "
            << std::count_if(values.begin(), values.end(), is_string) << std::endl;
    }


    das andere werde ich mal testen... mit dem +5
    Nachtrag: mhhh das geht auch nicht...

    hier mein Code + Fehlermeldung:
    Code:
    many::iterator it  = values.begin();  //erzeuge Iterator it und setze auf values.begin()
    
    // Fehlermeldung: 
    // input.cpp:72: no match for `std::_List_iterator<boost::any, boost::any&,
    // boost::any*>& += int' operator
    
    Zeile 72:    it +=2;
                   values.erase(it);  //löscht den Wert "wird gelöscht" (das 3te Element)
    vielleicht ist es jetzt klarer...
    Geändert von ufosworld (28-06-2007 um 11:31 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •