I have a vector of smart ptr of my class 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;
I have this working nicely:
tFooVec foo_vector; // insert couple of elements
size_t count = count_if( foo_vector.begin(), foo_vector.end(), std::tr1::mem_fn( &Foo::isEnabled ) );
But what functional "helper" to use when I want to count_if the "disabled" Foo objects
size_t count = count_if( foo_vector.begin(), foo_vector.end(), std::not1( std::tr1::mem_fn( &Foo::isEnabled ) ) ); // does not compile
above line 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
(Using g++ 4.1.2 on Linux)
I think the compile problem comes from the fact that std::not1 is using std::unary_negate which requires that the function / Predicate provided Predicate::argument_type . The latter is given when the Predicate is derived from std::unary_function sigh
Having said this I assume that std::tr1::mem_fn is not using std::unary_function nor providing the argument_type.
The solution I am now using is, that I am now using boost::bind instead of 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 )) );
To avoid complications (and confusion), I replacde the usage of std::tr1::bind with boost::bind throughout my code.
!boost::bind(... works for me:
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)));
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With