C++ メンバー関数ポインターと STL アルゴリズム
-
12-09-2019 - |
質問
Operator() をオーバーロードする抽象ファンクター クラスと、それを実装する派生オブジェクトがあります。
これらのファンクター クラスの配列を取得し、メンバー関数へのポインターを標準アルゴリズム 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)を実装する必要があります。 ) 関数。
for_each() 関数がメンバー関数 Operator()(param x) を呼び出せるようにする必要があるだけです。具体的な実装があり、それらのインスタンスを渡すだけで機能する別の関数があります。ここでも同様の効果を達成しようとしていますが、どのような具体的なクラスが与えられるのかはわかりません。
私の何が間違っているのでしょうか?
解決
あなたが何をしたいのか理解できれば、コードスニペットにはかなりの数のエラーがあります。
sizeof aArr
それは間違っています。サイズを明示的に渡す必要があります (ChrisW によって指摘されました)- ない
virtual
元の宣言の指定子operator()()
- どこにいるかわからない
for
一致するものがないためループが終了します}
(本来は存在しないはずだと思いますが)
以下は、配列をループするコードです。 A
(または A
-derived) オブジェクトと呼び出し 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()
次に、そこから、に提供された引数を固定する 1 パラメーターの関数オブジェクトを生成します。 function()
2 番目の引数として。(for_each()
1 パラメーターの関数ポインターまたは関数オブジェクトが必要です)。
編集: に基づく アレックス・ティングルの答え, 、おそらくあなたが望んでいたのではないかと推測します function()
1 台で多くのことを行う 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]));
}
}
他のヒント
あなたはこのような何かをしたい...
std::for_each(
it->second.begin(),
it->second.end(),
std::bind1st(std::mem_fun(&A::operator()),x)
);
表現「バー。* FN」、定期的に、または非メンバー関数ポインタに評価されません。 だから、このような機能を得るために、結合機能を呼び出す(のstd ::いずれかTR1 ::バインドまたは後押し::バインド)する必要があります。
私はそれが現在の形式を使用して動作し得ることができませんでした、私はそれは私がベースメンバ関数へのポインタを使用して、そのような派生クラスの実装を呼び出すようにしようとしているという事実が好きではありませんだと思います。
の代わりに私が実施されるとき、各派生クラスのファンクタが返される基本クラスに純粋仮想関数を含むようにコードを変更しました。私は仕事と何かを考えることはできません。しかし、それは次のようにコンパイルします。
しかし、誰もが、基本クラスに純粋仮想「ファンクタを作成する」の方法を使用することなく、元の問題への解決策を持っている場合、私は好奇心旺盛です。