我有一个我的班级Foo智能ptr的载体:
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 ) );
但是当我想要count_if“禁用”Foo对象时使用什么功能“助手”
size_t count = count_if( foo_vector.begin(), foo_vector.end(), std::not1( std::tr1::mem_fn( &Foo::isEnabled ) ) ); // does not compile
以上行无法编译:
/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
(在Linux上使用g ++ 4.1.2)
我认为编译问题来自于std::not1
正在使用std::unary_negate
这需要函数/谓词提供Predicate::argument_type
的事实。当谓词派生自std::unary_function
叹息
话虽如此,我假设std::tr1::mem_fn
未使用std::unary_function
,也未提供argument_type
。
我现在使用的解决方案是,我现在使用boost :: bind而不是std :: tr1 :: bind
#include <boost/bind.hpp>
using namespace boost;
...
size_t countboost = count_if( foo_vector.begin(), foo_vector.end(), !( bind( &Foo::isEnabled, _1 )) );
为了避免并发症(和混淆),我在我的代码中用boost :: bind替换了std :: tr1 :: bind的用法。
答案 0 :(得分:2)
!boost :: bind(...适合我:
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)));
};
答案 1 :(得分:0)
根本问题是mem_fun(isEnabled)
需要const Foo *
,而算法count_if
会将shared_ptr<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 ) ) );