オブジェクトの非静的メソッドDummyを別のオブジェクトの関数に渡すことができました。そのメソッドの参照を関数のオブジェクトに格納しようとすると問題が発生します。その方法がわかりません。
#include <iostream>
#include <functional>
class Dummy{
public:
void runDummyArgs(int z){std::cout<<"TEST: "<<z<<std::endl;};
};
class Test{
public:
template<typename X , typename T>
void runTest(X* obj, T(X::* func), int z) { (obj->*func)(z); };
/* It works, but I would like to store (obj->*func) in this class as a reference to reuse it when it is needed. */
};
int main()
{
Dummy *a = new Dummy();
Test *b = new Test();
b->runTest(a, &Dummy::runDummyArgs, 99);
return 0;
}
私は次のようなものを書きます:
#include <iostream>
#include <functional>
class Dummy{
public:
void runDummyArgs(int z){std::cout<<"TEST: "<<z<<std::endl;};
};
class Test{
std::function<void(int)> mFunc; // added member to hold function
public:
// added constructor to accept function
Test(std::function<void(int)> func): mFunc(func)
{
}
// no longer needs any templating. It's all handled by std::function
// most of the parameters bound by std::function
void runTest(int z)
{
mFunc(z);
};
};
int main()
{
Dummy a; // no need for dynamic allocation. Only use new when forced
// and that's almost never thanks to containers and smart pointers
// This line gets a bit weird. I'll explain it below
Test b([&a](int z){a.runDummyArgs(z);});
b.runTest(99); // just needs the end argument of the function
return 0;
}
OK。それはそれほど悪くはありません。を除いて
Test b([&a](int z){a.runDummyArgs(z);});
Test
std::function
を取り、int
何も返さないが必要です。[&a](int z){a.runDummyArgs(z);}
はラムダ式(ぎこちないビットと詳細に入る詳細なドキュメント)であり、を受け取り、int
何も返さない呼び出し可能なオブジェクトを定義します。結果のインスタンスはと呼ばれb
ます。ラムダをさらに分解する:
[&a]
a
参照によって変数をキャプチャします。これによりa
、ラムダ内の変更が可能になります。a
たとえばa
、関数が後で呼び出されたときに存在しない一時変数である場合、ラムダに独自のコピーを実行させたい場合があります。ダングリング参照とconst Dummy
コンパイラエラーに関する一般的な将来の質問を回避するためにmutable
、この回答の最後に値によるキャプチャの簡単な例を追加します。
(int z)
ラムダのパラメーター
{a.runDummyArgs(z);}
呼び出す関数本体runDummyArgs
の上にa
。
可変値の例によるより複雑なキャプチャ:
#include <iostream>
#include <functional>
class Dummy{
int val = 0; // provide some visible state for instances
public:
void runDummyArgs(int z)
{
std::cout<<"TEST: "<<z + val << std::endl;
// ^ added to show changing state
val++; // change state
}
};
class Test{
std::function<void(int)> mFunc;
public:
Test(std::function<void(int)> func): mFunc(func)
{
}
void runTest(int z)
{
mFunc(z);
};
};
std::function<void(int)> builder()
{
Dummy a;
return [a](int z)mutable{a.runDummyArgs(z);};
// ^ the copy of a can be modified.
} // a goes out of scope here, but its copy in the lambda lives on
int main()
{
Test b(builder());
b.runTest(99); // print 99
b.runTest(99); // print 100
Test c(builder());
c.runTest(99); // print 99 because we have a copy of a different dummy instance
c.runTest(99); // print 100
return 0;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加