3

私は私のクラス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 ) );

しかし、「無効にされた」Fooオブジェクトをcount_ifしたいときに使用する機能的な「ヘルパー」

 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_negatePredicate::argument_typestd::unary_function

これを言っても、私はそれstd::tr1::mem_fnがを使用std::unary_functionも提供もしていないと思いargument_typeます。

私が現在使用している解決策は、std :: tr1::bindの代わりにboost::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に置き換えます。

4

2 に答える 2

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)));
  };
于 2012-05-07T14:25:21.753 に答える
0

根本的な問題は、アルゴリズムがその述語にaを渡すのに対し、mem_fun(isEnabled)がかかることです。const Foo *count_ifshared_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 ) ) );
于 2012-05-07T15:53:56.913 に答える