У меня есть вектор умного ptr моего класса Foo:
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
(Используя g++ 4.1.2 в Linux)
Я думаю, что проблема компиляции возникает из-за того, что std::not1
использует std::unary_negate
, что требует, чтобы функция / Predicate предоставила 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 во всем своем коде.
size_t count = v.size() - std::count_if( v.begin(), v.end(), std::tr1::mem_fn(&Foo::isEnabled));
. Иногда самый простой ответ — избежать проблемы. - person David Rodríguez - dribeas   schedule 07.05.2012