3

operator() をオーバーロードする抽象ファンクター クラスと、それを実装する派生オブジェクトがあります。

これらのファンクター クラスの配列を取り、メンバー関数へのポインターを std アルゴリズム for_each() に渡そうとする関数 (別のクラスの一部) があります。

編集:私はそれを再洗浄し、明確にするために古い小さな例を入れました。

class A{
  operator()(x param)=0;
  operator()(y param)=0;
}

class B: public A{
  operator()(x param); //implemented
  operator()(y param);
}
...// and other derived classes from A

void ClassXYZ::function(A** aArr, size_t aSize)
{
  ...//some code here

  for(size_t i = 0; i< aSize; i++){

    A* x = aArr[i];
    for(v.begin(), v.end(), ...//need to pass pointer/functor to right operator() of x here

..//other code
}

いくつかの方法を試しましたが、それを機能させる方法がわかりません。異なる派生型を持つことができるため、抽象型を使用する必要がありますが、それらはすべて同じ operator()(param x を実装する必要があります) 関数。

メンバ関数 operator()(param x) を呼び出せるようにするには、for_each() 関数が必要です。具体的な実装があり、それらのインスタンスを渡すだけで機能する別の関数があります。ここで同様の効果を達成しようとしていますが、どの具体的なクラスが与えられているかを知りません。

私は何を間違っていますか?

4

4 に答える 4

4

あなたはこのようなものが欲しい...

std::for_each(
  it->second.begin(),
  it->second.end(),
  std::bind1st(std::mem_fun(&A::operator()),x)
);
于 2009-09-20T15:31:48.247 に答える
3

あなたが何をしたいのか理解できれば、あなたのコード スニペットにはかなりの数のエラーがあります。

  • sizeof aArrサイズを明示的に渡す必要があります (ChrisW が指摘)
  • virtualの元の宣言に指定子がありませんoperator()()
  • for一致するものがないため、ループがどこで終了するかわかりません}(まったく存在しないはずです)

以下は、渡された引数をパラメーターとして渡して、A(または派生した) オブジェクトの配列をループし、各Aオブジェクトを呼び出すコードです。operator()param

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

typedef double param;      // Just for concreteness

class A {
public:
    virtual void operator()(param x) = 0;
};

class B : public A {
public:
    void operator()(param x) { cerr << "This is a B!  x==" << x << ".\n"; }
};

void function(A** aArr, size_t n, param theParam) {
    void (A::*sFunc)(param x) = &A::operator();
    for_each(aArr, aArr + n, bind2nd(mem_fun(sFunc), theParam));
}

int main(int argc, char** argv) {
    A* arr[] = { new B(), new B(), new B() };

    function(arr, 3, 42.69);

    delete arr[0];
    delete arr[1];
    delete arr[2];
    return 0;
}

mem_fun()1 パラメーターのメンバー関数ポインターを 2 パラメーターの関数オブジェクトに変換する必要があります。bind2nd()次に、2 番目の引数として指定された引数を固定する 1 パラメーターの関数オブジェクトを生成しfunction()ます。( for_each()1 パラメーターの関数ポインターまたは関数オブジェクトが必要です。)

編集: Alex Tingle's answerに基づいてfunction()、単一のA派生オブジェクトで多くのことをしたいと思っていたのではないかと推測します。その場合、次のようなものが必要になります。

void function(A** aArr, size_t n, vector<param> const& params) {
    for (size_t i = 0; i < n; ++i) {
        void (A::*sFunc)(param x) = &A::operator();
        for_each(params.begin(), params.end(), bind1st(mem_fun(sFunc), aArr[i]));
    }
}
于 2009-09-20T15:47:11.553 に答える
1

式 "bar.*fn" は、通常の、または非メンバーの関数ポインターとして評価されません。したがって、そのような関数を取得するには、バインド関数 ( std::tr1::bind または boost::bind のいずれか) を呼び出す必要があります。

于 2009-09-20T15:15:42.417 に答える
0

現在の形式を使用して動作させることができませんでした。ベースメンバー関数へのポインターを使用して、そのような派生クラスの実装を呼び出そうとしているという事実は気に入らないと思います。

代わりに、実装時に各派生クラスのファンクターを返す純粋仮想関数を基本クラスに含めるようにコードを変更しました。私は他にうまくいくことは考えられません。しかし、それはこのようにコンパイルされます。

しかし、基本クラスで純粋な仮想「ファンクターの作成」メソッドを使用せずに、元の問題の解決策を誰かが持っているかどうかは興味があります。

于 2009-09-20T18:24:52.860 に答える