【发布时间】:2012-05-07 14:07:38
【问题描述】:
我有一个我的类 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 。后者在 Predicate 派生自 std::unary_function sigh
话虽如此,我假设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 )) );
为避免复杂化(和混淆),我在整个代码中将 std::tr1::bind 的用法替换为 boost::bind。
【问题讨论】:
-
如果您可以使用更新的编译器 (C++11),则可以使用 lambda。
-
很想...不能 - 我的代码编译所在的系统不属于我自己。更糟糕的是,我的代码也必须在 AIX 上用 xlC 编译。所以,我坚持使用“老式”函子。
-
荒谬的答案:
size_t count = v.size() - std::count_if( v.begin(), v.end(), std::tr1::mem_fn(&Foo::isEnabled));。有时最简单的答案是避免问题。 -
count_if 只是一个例子......我也在寻求应用 remove_copy_if。也许我也应该在我的例子中使用它。