2012-05-07 2 views
3

나는 내 수업 푸의 스마트 PTR의 벡터가 :어떤 대안은 성병 :: not1는 표준 : TR1 :: 바인드 또는 표준을 사용할 때 사용되는 :: 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)); 

하지만 "비활성"푸 라인 위의

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

객체 count_if하고자 할 때 어떤 기능 "도우미"를 사용하는 C하지 않습니다 ompile :

는 (리눅스 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 

나는 컴파일 문제가 기능/술어가 Predicate::argument_type를 제공해야합니다 std::not1std::unary_negate을 사용하고 있다는 사실에서 유래 생각합니다. 술어가 나는 std::tr1::mem_fnstd::unary_function를 사용이나 argument_type 제공되지 않는 것으로 가정 std::unary_function한숨이 상기 데

으로부터 유도 될 때, 후자가 주어진다.

는 내가 지금 지금 부스트를 사용하고 대신 표준 : 합병증 (혼란)을 방지하기 위해

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

TR1 :: 바인딩의 결합 :: 것으로, IS 사용하고이 솔루션은, 나는의 사용을 replacde

std :: tr1 :: bind with boost :: bind 내 코드에서. !

+2

최신 컴파일러 (C++ 11)를 사용할 수 있으면 대신 람다를 사용할 수 있습니다. – stefaanv

+0

은 ... 내 코드가 컴파일 된 시스템이 나 혼자 소유하지 않을 수는 없습니다. 그리고 나쁘게하려면, 내 코드는 AIX에서도 xlC로 컴파일해야합니다. 그래서, 저는 "고풍스러운"펑터를 고집합니다. –

+1

Absurd 대답 :'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 : 오류 : '연산자!'와 일치하지 않습니다. in! ':: st1 :: tr1 :: mem_fn [_Tp = bool()() const, _Class = Foo] (& Foo :: isEnabled)' ../src/shared_ptr_tests.cpp:217 : 참고 : 후보자는 연산자입니다. ! (bool)

+0

@CarstenGreiner 어떤 버전의 부스트를 사용합니까? 이 기능은 오래된 1.33 부스트에 추가되었습니다. – pmr

+0

어 - 우리는 처음에 부스트에 대해 이야기하는 것이 아니라 std :: tr1 - tr1이 부스트에서 구현된다는 것을 알고 있지만 잘 부스트를 포함하지는 않습니다. 그래서, 예, 1_44를 제자리에 밀어 넣었습니다.하지만 여기서 저는 자신을 std : tr1 자료로 제한합니다. (어쩌면 나는 부스트를 사용하여 다시 생각해 보았다). 현재 사용 –

0

근본적인 문제는 mem_fun(isEnabled)이 알고리즘 반면 count_if이 조건에 shared_ptr<Foo>을 통과하는 const Foo * 소요입니다

. 나는 그게 왜 과 함께 작동하는지 완전히 확신하지는 않지만, 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))); 
관련 문제