template <typename Ret, typename... Args>
class MyDelegate{
std::vector<Ret(*)(Args...)> vec;
public:
void operator+=( const Ret(*)(Args...)& newElement)
{
vec.push_back(newElement);
}
Ret operator()(const Args&... args)
{
for (auto i = vec.begin(); i != vec.end(); ++i)
(*i)(args...);
}
};
正如您所看到的,我希望这个类能够以这种方式使用:
MyDelegate<void> voidDelegate;
MyDelegate<void, int> intDelegate;
MyDelegate<int, char, boolt> miscDelegate;
使用+ =运算符和“添加”函数,例如:
voidDelegate += voidFunc;
//etc...
我现在遇到+ =运算符问题,因为VS不接受这个:
MyDelegate<void, int> delegate1;
delegate1 += [](const int a)->void{std::cout << a << std::endl; };
lambda函数是正确的:它接受一个int并返回void,所以我不明白什么是错的。
答案 0 :(得分:3)
问题是你的std::vector
存储函数指针。它不存储std::bind
个对象,它不存储成员函数,它不存储函子并且它不存储lambda。您正在尝试向其添加lambda,因此失败。
如果你想存储任何支持使用正确的参数和返回类型调用的对象,你需要std::function
:
using FunType = std::function<Ret(Args...)>;
std::vector<FunType> vec;
顺便提一下,您可以通过完善转发operator()
args并在界面中复制newElement
arg并将其移至std::vector
来改善您的解决方案。
答案 1 :(得分:1)
您的委托只接受函数指针。 lambda不是函数指针。但是,你想要的lambda并没有捕获任何东西。这意味着,由于some sorcery:
,它可以转换为函数指针MyDelegate<void, int> delegate1;
delegate1 += +[](const int a)->void{std::cout << a << std::endl; };
↑↑↑
但是,一旦你想允许具有成员变量的仿函数,额外的+
就不会起作用:
delegate1 += +[x](const int a) { ... }; // error: no match for operator+
此时您必须使用std::function
的{{3}}建议。
答案 2 :(得分:0)
@ TartanLlama&right-right,std :: function就是你所需要的。
调用循环可折叠为for (auto handler : vec) handler(args...);