std::find und boost::bind !?



  • Also ich habe eine Klasse Entity:

    class Entity {
            public:
                typedef boost::shared_ptr<Entity> type;
                typedef std::list<type> list_t;
                typedef std::list<type>::iterator iterator;
    
            private:
                std::string id;
                list_t nodes;
            public:
                Entity(std::string id);
                void add_entity(type &e);
                list_t::iterator begin();
    
                list_t::iterator end();
    
                const std::string getId();
    
                // comparison structure
                struct Compare: std::binary_function<Entity &, std::string, bool> {
                        result_type operator()(first_argument_type a, second_argument_type b) {
                            return (a.getId() == b);
                        }
                };
        };
    

    wiie man sehen kann, gehts hier um eine Art Baumstruktur.
    Jetzt möchte ich also ein Kindelement anhand der Id finden.. Dazu hab ich eine abgeleitete Klasse und eine Funktion zum suchen:

    Entity::type Memory::find(std::string id) {
            Entity::type result;
    
    //        result = std::find(begin(), end(), std::bind2nd(std::mem_fun_ref(&Entity::Compare()), id));
            result = std::find(begin(), end(), boost::bind(&Entity::Compare(), _2, id));
            return result;
        }
    

    uuund der compiler meckert:

    mein gcc sag dazu

    **** Build of configuration Debug for project 01MemorySegments ****

    make all
    Building file: ../Entities.cpp
    Invoking: GCC C++ Compiler
    g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"Entities.d" -MT"Entities.d" -o"Entities.o" "../Entities.cpp"
    ../Entities.cpp: In member function ‘boost::shared_ptrdocjunior::Entity docjunior::Memory::find(std::string)’:
    ../Entities.cpp:66: warning: taking address of temporary
    /usr/include/boost/bind.hpp: At global scope:
    /usr/include/boost/bind.hpp: In instantiation of ‘boost::_bi::result_traits<boost::_bi::unspecified, docjunior::Entity::Compare*>’:
    /usr/include/boost/bind/bind_template.hpp:15: instantiated from ‘boost::_bi::bind_t<boost::_bi::unspecified, docjunior::Entity::Compare*, boost::_bi::list2<boost::arg<2> ()(), boost::_bi::value<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >’
    ../Entities.cpp:68: instantiated from here
    /usr/include/boost/bind.hpp:66: error: ‘docjunior::Entity::Compare
    ’ is not a class, struct, or union type
    ../Entities.cpp: In member function ‘boost::shared_ptrdocjunior::Entity docjunior::Memory::find(std::string)’:
    ../Entities.cpp:68: error: no match for ‘operator=’ in ‘result = std::find [with _IIter = std::_List_iterator<boost::shared_ptrdocjunior::Entity >, _Tp = boost::_bi::bind_t<boost::_bi::unspecified, docjunior::Entity::Compare*, boost::_bi::list2<boost::arg<2> ()(), boost::_bi::value<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >](((docjunior::Memory)this)->docjunior::Memory::<anonymous>.docjunior::Entity::begin(), ((docjunior::Memory*)this)->docjunior::Memory::<anonymous>.docjunior::Entity::end(), ((const boost::_bi::bind_t<boost::_bi::unspecified, docjunior::Entity::Compare*, boost::_bi::list2<boost::arg<2> ()(), boost::_bi::value<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)((const boost::_bi::bind_t<boost::_bi::unspecified, docjunior::Entity::Compare, boost::_bi::list2<boost::arg<2> ()(), boost::_bi::value<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >)(& boost::bind(F, A1, A2) [with F = docjunior::Entity::Compare*, A1 = boost::arg<2> ()(), A2 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >](<unnamed>::_2, std::basic_string<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >)(& id)))))))))’
    /usr/include/boost/shared_ptr.hpp:177: note: candidates are: boost::shared_ptr<T>& boost::shared_ptr<T>::operator=(const boost::shared_ptr<T>&) [with T = docjunior::Entity]
    /usr/include/c++/4.3/bits/stl_algo.h: In function ‘_InputIterator std::__find(_InputIterator, _InputIterator, const _Tp&, std::input_iterator_tag) [with _InputIterator = std::_List_iterator<boost::shared_ptrdocjunior::Entity >, _Tp = boost::_bi::bind_t<boost::_bi::unspecified, docjunior::Entity::Compare*, boost::_bi::list2<boost::arg<2> ()(), boost::_bi::value<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’:
    /usr/include/c++/4.3/bits/stl_algo.h:3814: instantiated from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = std::_List_iterator<boost::shared_ptrdocjunior::Entity >, _Tp = boost::_bi::bind_t<boost::_bi::unspecified, docjunior::Entity::Compare
    , boost::_bi::list2<boost::arg<2> ()(), boost::_bi::value<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’
    ../Entities.cpp:68: instantiated from here
    /usr/include/c++/4.3/bits/stl_algo.h:151: error: no match for ‘operator==’ in ‘__first.std::_List_iterator<_Tp>::operator
    [with _Tp = boost::shared_ptrdocjunior::Entity]() == __val’
    make: *** [Entities.o] Fehler 1

    Mein Verständnis in der Richtung ist arg begrenzt, aaber gerade jetzt brauch ich sowas halt..
    Wie kann ich also die compare-funktion für mein find aufrufen?


  • Mod

    DocJunioR schrieb:

    boost::bind(&Entity::Compare(), _2, id)
    

    Ohne die Fehlermeldung studiert zu haben: Entity::Compare() ist ein rvalue, der Adressoperator arbeitet nur mit lvalues.
    Hm.. der Compiler gibt dazu sogar eine Warnung aus.
    Selbst wenn das Adresse ermitteln möglich wäre, hättest du dann nur einen einfachen Zeiger...

    Soll vermutlich so aussehen:

    boost::bind(Entity::Compare(), _2, id)
    

    oder du machst aus Enitity::Compare eine nichtstatische Memberfunktion. Dann sollte es auch mit der kommentierten Version klappen.



  • da bleibt dann trotzdem noch folgendes:

    Description Resource Path Location Type
    no match for ‘operator==’ in ‘__first.std::_List_iterator<_Tp>::operator* [with _Tp = boost::shared_ptrdocjunior::Entity]() == __val’ 01MemorySegments line 151, external location: /usr/include/c++/4.3/bits/stl_algo.h C/C++ Problem


  • Mod

    DocJunioR schrieb:

    da bleibt dann trotzdem noch folgendes:

    Description Resource Path Location Type
    no match for ‘operator==’ in ‘__first.std::_List_iterator<_Tp>::operator* [with _Tp = boost::shared_ptrdocjunior::Entity]() == __val’ 01MemorySegments line 151, external location: /usr/include/c++/4.3/bits/stl_algo.h C/C++ Problem

    Ich könnte zwar raten, aber letztlich reicht der Code nicht aus. Schon weil unklar bleibt, was begin und end für Iteratoren sind.



  • begin() und end() sind delegatoren und zeigen auf begin() und end() der liste



  • was du willst ist std::find_if nicht std::find

    Regards,



  • das ist zwar richtig, hilft aber auch nicht.
    hab jetzt mal einfach nen workaround über ne map realisiert und les mir das thema nochmal genauer durch, wenn ich die zeit hab..



  • war mist


Anmelden zum Antworten