我有一个注册回调函数的类,稍后会调用它们。
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;
}
我今天听到了Stephan T. Lavavej的一个演讲,他说的其中一件事就是应该避免使用std :: bind并使用lambdas。所以为了学习新东西,我想我会尝试将mfunc2中的std :: bind调用更改为lambda,但我对模板很新,并且无法弄清楚如何生成我想要的代码。
带有make_int_sequence的当前placeholder_template我在这里找到了SO,但是我无法真正理解它是如何工作的,或者在哪里找到任何好的阅读......
Args ...保存lambda应该接受的参数类型,但我需要以某种方式根据sizeof ...(Args)创建变量名称,如var1,var2,var3等,然后将它们合并在一起
所以例如&lt; int,int,int&gt;,Args ...将保存int,int。 然后我想将lambda构造为
[func, &instance](int var1, int var2) -> ReturnType { return func(&instance, var1, var2); }
我怎么能做到这一点?
答案 0 :(得分:4)
这应该做的工作:
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) {
function.push_back([&instance, func](Args&&... args) {
return (instance.*func)(std::forward<Args>(args)...);
});
}
};
请注意,在operator()中,除了最后一个值之外,基本上都会丢弃所有返回值。这种行为是否打算?