質問

コード全体でテンプレートを増殖させずにstlアルゴリズムfor_eachを使用しようとしています。 std :: for_eachは、値によってMyFunctorクラスをインスタンス化したいのですが、それは抽象化できません。ポインターを渡し、必要に応じて逆参照するファンクターアダプタークラスを作成しました。

私の質問:

STLまたはBoostにはすでにそのようなアダプタークラスがありますか?車輪を再発明する必要はありません!

 struct MyFunctor  {
     virtual ~MyFunctor() {}
     virtual void operator()(int a) = 0; 
 }

 namespace {
     template<typename FunctorType, typename OperandType> struct
 FunctorAdapter
     {
         FunctorAdapter(FunctorType* functor) : mFunctor(functor) {}
         void operator()(OperandType& subject)
         {
             (*mFunctor)(subject);
         }

         FunctorType* mFunctor;
     }; }

 void applyToAll(MyFunctor &f) {
     FunctorHelper<MyFunctor, int> tmp(&f);
     std::for_each(myvector.begin(), myvector.end(), tmp); }

乾杯、

デイブ

役に立ちましたか?

解決

tr1 :: refはここであなたを助けるかもしれません---それは、標準のアルゴリズムを参照することにより、バインドまたは関数オブジェクト(抽象オブジェクトでも)への参照によって通常のオブジェクトを渡すことができるように、参照ラッパーであることを意味します。

// requires TR1 support from your compiler / standard library implementation
#include <functional>

void applyToAll(MyFunctor &f) {
    std::for_each(
        myvector.begin(), 
        myvector.end(), 
        std::tr1::ref(f) 
    ); 
}

ただし、decltypeをサポートしていないコンパイラーは、抽象型への参照の受け渡しを拒否することに注意してください...したがって、C ++ 0xサポートを取得するまで、このコードはコンパイルできません。

他のヒント

functional の関数アダプター(およびそのシム)を使用できます。

#include <functional>

using namespace std;
for_each( vec.begin(), vec.end(), :mem_fun_ptr( &MyClass::f ) );

コンテナにオブジェクトへのポインタが含まれている場合は、 mem_fun_ptr を使用し、そうでない場合は mem_fun を使用します。これらの隣に、1つの引数を取るメンバー関数のラッパーがあります: mem_fun1_ptr および mem_fun1

@Evan:実際、各オブジェクトに対して同じ引数を使用してメンバー関数を呼び出すことができます。 mem_fun1 ラッパーの最初の引数は this ポインターで、2番目はメンバー関数の引数です:

for_each( vec.begin(), vec.end(), bind2nd( mem_fun_ptr( &MyClass::f ), 1 ) );

引数が増えると、ループを自分で作成したり、引数を表すconstメンバー変数を持つカスタムファンクターを作成したりするのが読みやすくなります。

Boost :: Function

正しく覚えていれば、ヘッダーのみのライブラリでもあるため、簡単に使用できます。

ファンクターポインターのラッピングをすべて忘れて、代わりに bind(functor_pointer、mem_fun1(&amp; MyFunctor :: operator());  ファンクターとして?そうすれば、どのような形や形式でもコピーを管理する必要はありません。

@xtoflの答えに基づいて構築します。配列には&quot; this&quot;ではなくintが含まれるためポインタ、正しい呪文は

だと思います
class MyClass
{
  virtual void process(int number) = 0;
};
MyClass *instance = ...;

for_each( vec.begin(), vec.end(), binder1st(instance, mem_fun_ptr(&MyClass::process) );

@xtoflのコードとの唯一の違いは、バインダー2ではなくバインダー1です。バインダ2ndを使用すると、さまざまな「これ」に同じ番号を渡すことができます。ポインター。バインダ1stを使用すると、さまざまな番号を1つの「this」に渡すことができます。ポインター。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top