2009-06-02 4 views
1

Erwägen Sie folgendes Beispiel:Negator Adapter in STL

#include <iostream> 
#include <functional> 
#include <algorithm> 
#include <vector> 

#include <boost/bind.hpp> 

const int num = 3; 

class foo { 
private: 
    int x; 
public: 
    foo(): x(0) {} 
    foo(int xx): x(xx) {} 
    ~foo() {} 
    bool is_equal(int xx) const { 
     return (x == xx); 
    } 
    void print() { 
     std::cout << "x = " << x << std::endl; 
    } 
}; 

typedef std::vector<foo> foo_vect; 

int 
main() { 
    foo_vect fvect; 
    for (int i = -num; i < num; i++) { 
     fvect.push_back(foo(i)); 
    } 
    foo_vect::iterator found; 
    found = std::find_if(fvect.begin(), fvect.end(), 
     boost::bind(&foo::is_equal, _1, 0)); 
    if (found != fvect.end()) { 
     found->print(); 
    } 
    return 0; 
} 

Gibt es eine Möglichkeit, eine Art negator Adapter mit foo::is_equal() verwenden ersten Nicht-Null-Element zu finden. Ich möchte nicht foo::is_not_equal(int) Methode schreiben, glaube ich, es gibt einen besseren Weg. Ich habe versucht, mit std::not2 zu spielen, aber ohne Erfolg.

Antwort

3

Da Sie Boost.Bind verwenden:

std::find_if(fvect.begin(), fvect.end(), 
    !boost::bind(&foo::is_equal, _1, 0) 
); 

(Hinweis der "!")

2

Das Argument zu std::not2 muss wie ein "normales" binäres Prädikat aussehen, also müssen Sie foo::is_equal mit etwas wie std::mem_fun_ref anpassen. Sie sollen wie etwas tun können:

std::not2(std::mem_fun_ref(&foo::is_equal)) 
2

Wenn Sie einstelligen functors verwenden (

struct odd : public std::unary_function<int,bool> 
{ 
    bool operator()(int data) const { 
     return data % 2; 
    } 
}; 
void f(std::vector<int> const & v) 
{ 
    std::vector<int>::const_iterator first_odd 
     = std::find_if(v.begin(), v.end(), odd()); 
    std::vector<int>::const_iterator first_even 
     = std::find_if(v.begin(), v.end(), std::not1(odd())); 
} 

Aber das funktioniert nicht mit dem unspecified_t: im STL Sinne) können Sie std :: not1 verwenden ype das von boost :: bind zurückgegeben wird. Dafür können Sie, wie bereits von Éric beschrieben, das! Operator über die unspecified_type zurückgegeben.