私は、コールバック関数を登録し、後でこのように呼び出すクラスを持っています。クラステンプレートからラムダを生成する
template<typename ReturnType, typename... Args>
class Signal {
std::vector<std::function<ReturnType(Args...)>> function;
public:
template<typename... Args2>
ReturnType operator()(Args2&&... args2) {
ReturnType ret;
for (auto& func : function)
ret = func(std::forward<Args2>(args2)...);
return ret;
}
template<typename Func>
void func(Func const &func) {
function.push_back(std::function<ReturnType(Args...)>(func));
}
template<typename Class, typename Instance>
void mfunc(ReturnType(Class::*func)(Args...), Instance &instance) {
mfunc2(func, instance, make_int_sequence<sizeof...(Args)>{});
}
template<typename Class, typename Instance, int... I>
void mfunc2(ReturnType(Class::*func)(Args...), Instance &instance, int_sequence<I...>) {
using namespace std::placeholders;
function.push_back(std::function<ReturnType(Args...)>(std::bind(func, &instance, placeholder_template<I>{}...)));
}
};
#include <iostream>
class foo {
public:
int bar(int x, double y) {
std::cout << x << " and " << y << std::endl;
return x*2;
}
};
int main() {
foo foo1;
Signal<int, int, double> sig;
sig.mfunc(&foo::bar, foo1);
std::cout << "Return: " << sig(5,5.5) << std::endl;
}
今日はステファン・T. Lavavejから話を聞いた、と彼は言っていたことの一つは、STD ::バインドは避け、代わりにラムダを使用しなければならないということです。新しいことを学ぶために、私はmfunc2のstd :: bind呼び出しをラムダに変更しようと考えていましたが、テンプレートが新しく、必要なコードを生成する方法を理解できません。
私はSOにここで見つけるmake_int_sequenceで現在placeholder_templateが、私は実際にそれ上の任意の良い読書を見つける方法を正確にそれが動作、またはどこの周り私の頭をラップすることはできません...
のArgs ...ラムダが受け入れるべき引数型を保持していますが、sizeof ...(Args)に応じてvar1、var2、var3などの変数名を作成し、それらを一緒にマージする必要があります。
たとえば、< int、int、int>、Args ...はint、intを保持します。 は、私は、私はこれを達成する可能性がどのように
[func, &instance](int var1, int var2) -> ReturnType { return func(&instance, var1, var2); }
としてラムダを構築したいですか?これは、仕事をする必要があります
[mcve]で始まります。コンパイルしたものを使って、バリデーションラムダを使用するように変更する方法を示すことができます。 – AndyG
テンプレート指定子を削除するために私の投稿を編集しました。したがって、戻り値の型(voidではない)と少なくとも1つの引数を指定する限り、コンパイルする必要があります。 – super