2012-05-07 4 views
3

私は私のクラスはFooのスマートPTRのベクトルを持っている:何の代替はstd ::へのstdを使用しているときNOT1を使用する:: TR1 ::バインドまたはのstd :: tr1を:: mem_fnの

struct Foo 
{ 
    Foo() : mEnabled(false) {} 

    bool mEnabled; 

    bool isEnabled() const { return mEnabled; } 
    void setEnabled(bool inEnabled) { mEnabled = inEnabled; } 
    /* ... */ 
}; 

typedef std::tr1::shared_ptr<Foo> tFooPtr; 

typedef std::vector<tFooPtr> tFooVec; 

私は、このうまく働いています:

tFooVec foo_vector; // insert couple of elements 
size_t count = count_if(foo_vector.begin(), foo_vector.end(), std::tr1::mem_fn(&Foo::isEnabled)); 

しかし、機能的なものを「ヘルパー」を使用するために、私は「無効」fooがC

size_t count = count_if(foo_vector.begin(), foo_vector.end(), std::not1(std::tr1::mem_fn(&Foo::isEnabled))); // does not compile 

線の上にいないオブジェクトをcount_ifしたいときにompile:

(Linux上でG ++ 4.1.2を使用して)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algo.h:446: error: no match for call to '(std::unary_negate<std::tr1::_Mem_fn<bool (Foo::*)()const> >) (std::tr1::shared_ptr<Foo>&)' 
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:322: note: candidates are: bool std::unary_negate<_Predicate>::operator()(const typename _Predicate::argument_type&) const [with _Predicate = std::tr1::_Mem_fn<bool (Foo::*)()const>] 
make: *** [src/shared_ptr_tests.o] Error 1 

私は、コンパイルの問題はstd::not1関数/述語がPredicate::argument_typeを提供することを必要とするstd::unary_negateを使用しているという事実から来ていると思います。述語が私はstd::tr1::mem_fnstd::unary_functionを使用してもargument_typeを提供していないと仮定std::unary_functionため息これを言った

に由来する場合、後者が与えられます。私は今、合併症(と混乱を)避けるために代わりのstdのバインド:: :: tr1を::バインド

#include <boost/bind.hpp> 
using namespace boost; 
... 
size_t countboost = count_if(foo_vector.begin(), foo_vector.end(), !(bind(&Foo::isEnabled, _1))); 

私は今のブーストを使用していますということであり、使用しています

ソリューションは、私はの使用をreplacde私のコード全体でboost :: bindとstd :: tr1 :: bind。 !

+2

最新のコンパイラ(C++ 11)を使用できる場合は、代わりにラムダを使用できます。 – stefaanv

+0

は私のコードがコンパイルされているシステムは自分で所有していないことができます。そしてそれを悪化させるために、私のコードはxlCでAIX上でコンパイルする必要があります。だから、私は "昔ながらの"ファンクタに固執しています。 –

+1

不合理な答え: 'size_t count = v.size() - std :: count_if(v.begin()、v.end()、std :: tr1 :: mem_fn(&Foo :: isEnabled))'。時には最も簡単な答えは問題を回避することです。 –

答えて

2

後押し::バインドを(...は、私の作品:

bool test(int i) 
    { 
    return i < 2; 
    } 

    TEST(boost_bind_test, negateTest) 
    { 
    std::vector<int> vec; 
    vec.push_back(1); 
    vec.push_back(2); 
    vec.push_back(3); 

    ASSERT_EQ(2, count_if(vec.begin(), vec.end(), !boost::bind(&test, _1))); 
    }; 
+0

size_t countN = count_if(foo_vector.begin()、foo_vector.end()、!(std :: tr1 :: mem_fn(&Foo :: isEnabled))); 結果: ../src/shared_ptr_tests.cpp:217:エラー: 'operator!'と一致しません。 '&lt; std :: tr1 :: mem_fn [_Tp = bool()()const、_Class = Foo](&Foo :: isEnabled)' ../src/shared_ptr_tests.cpp:217: !(bool)

+0

@CarstenGreinerどのバージョンのブーストを使用しますか?この機能は古風であるブースト1.33で追加されました。 – pmr

+0

えええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええええ、だから、ええ、私は1_44を増強していますが、ここでは自分をstd:tr1のものに制限します。 (多分私はブーストを使って再考する)。今使って –

0

根本的な問題がmem_fun(isEnabled)アルゴリズムに対しcount_ifは、その述語にshared_ptr<Foo>を渡して、const Foo *かかることである

。私は完全にはなぜそれが正常にmem_fn(&Foo::isEnabled)で動作しますが、not1(mem_fn(&Foo::isEnabled))で動作しません。余分なラッパーは、別の変換の必要性を紹介していると思うが、それを回避することができます:

bool sharedEnabled(tFooPtr x) { 
    return x->isEnabled(); 
} 

size_t count2 = std::count_if(foo_vector.begin(), foo_vector.end(), std::not1(std::ptr_fun(&sharedEnabled)));