Komplizierte Verkettung mit for_each und remove_if mit Binder bauen



  • Hallo, ich möchte das hier in ein for_each umwandeln:

    Pseudocode:
    
    intvector a, b
    for_each item in a
        if item is in b
            remove item in b
    

    In c++

    vector<int> a,b; // gefüllt bei mir ;)
    vector<int>::const_iterator it;
    for(it = a.begin(); it != a.end(); ++it) {
        vector<int>::iterator suche = find(b.begin(), b.end(), *it);
        if(suche != b.end()) {
            b.erase(suche);
        }
    }
    

    Kann ich das mit den Bindern der STL (kein Boost!) und for_each in ein Statement bekommen?

    Also:

    for_each(a.begin(), a.end(), /* ???? */);
    

    Irgendwas mit mem_fun und remove_if, aber ich bekomms net hin.

    Was passiert wenn man std::vector::erase auf das Ende aufruft, also auf std::vector::end()?


  • Mod

    Thomas (: schrieb:

    Hallo, ich möchte das hier in ein for_each umwandeln:

    Pseudocode:
    
    intvector a, b
    for_each item in a
        if item is in b
            remove item in b
    

    In c++

    vector<int> a,b; // gefüllt bei mir ;)
    vector<int>::const_iterator it;
    for(it = a.begin(); it != a.end(); ++it) {
        vector<int>::iterator suche = find(b.begin(), b.end(), *it);
        if(suche != b.end()) {
            b.erase(suche);
        }
    }
    

    Kann ich das mit den Bindern der STL (kein Boost!) und for_each in ein Statement bekommen?

    Also:

    for_each(a.begin(), a.end(), /* ???? */);
    

    Irgendwas mit mem_fun und remove_if, aber ich bekomms net hin.

    die binder und adapter der standardbibliothek arbiten nur mit funktionen, die einen oder 2 parameter haben. remove_if hat 3 parameter, ich bezweifle daher, dass das möglich ist.

    Thomas (: schrieb:

    Was passiert wenn man std::vector::erase auf das Ende aufruft, also auf std::vector::end()?

    undefiniertes verhalten. erase mit einem iterator löscht ein element - das impliziert, dass diese element existiert, der iterator also dereferenziert werden kann. erase mit 2 iteratoren (für den zweiten benutzen wir end() ) sollte allerdings funktionieren.



  • camper schrieb:

    die binder und adapter der standardbibliothek arbiten nur mit funktionen, die einen oder 2 parameter haben. remove_if hat 3 parameter, ich bezweifle daher, dass das möglich ist.

    Stimmt schade. Naja lass ich eben die Schleife.



  • Wie wärs damit:

    struct Eraser : public binary_function<int,vector<int>,bool> {
    
         result_type operator()(first_argument_type val,second_argument_type vec) 
         { 
                   if(find(vec.begin(),vec.end(),val) !=  vec.end()) return true;
                   return false;
         } 
    
    };
    
    ...
    ...
    
    b.erase(remove_if(b.begin(),b.end(),bind2nd(Eraser(),a)), b.end());
    

    Leider schluckt das der MinGW nicht, aber der neue Turbo C++.
    Also ist da wahrscheinlich noch nen Fehler der nicht "gesund" ist.

    MinGW:

    C:\Dev-Cpp\include\c++\3.4.2\bits\stl_function.h In member function `typename
     _Operation::result_type std::binder2nd<_Operation>::operator()(typename 
    _Operation::first_argument_type&) const [with _Operation = Eraser]': 
    
    1074 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_algo.h   instantiated from 
    `_OutputIterator std::remove_copy_if(_InputIterator, _InputIterator, 
    _OutputIterator, _Predicate) [with _InputIterator = 
    __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, 
    _OutputIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int, 
    std::allocator<int> > >, _Predicate = std::binder2nd<Eraser>]' 
    
    1149 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_algo.h   instantiated from 
    `_ForwardIterator std::remove_if(_ForwardIterator, _ForwardIterator, _Predicate)
     [with _ForwardIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int,
     std::allocator<int> > >, _Predicate = std::binder2nd<Eraser>]' 
    
    38 C:\Dev-Cpp\fffff.cpp   instantiated from here 
    
    446 C:\Dev-Cpp\include\c++\3.4.2\bits\stl_function.h passing `const Eraser' as 
    `this' argument of `bool Eraser::operator()(int, std::vector<int, 
    std::allocator<int> >)' discards qualifiers
    

  • Mod

    Freak_Coder schrieb:

    [...] discards qualifiers
    

    das verweist auf eine verbotene konvertierung, die const/volatile-qualifizierung ignoriert. und tatsächlich: der operator sollte const sein. in jedem falle ist das allerdings nicht gesuchte lösung, die ja ohne selbstgebaute prädikate auskommen sollte.



  • camper schrieb:

    das verweist auf eine verbotene konvertierung, die const/volatile-qualifizierung ignoriert. und tatsächlich: der operator sollte const sein.

    Jetzt funktionierts, danke.


Anmelden zum Antworten