在看到 Unity 的委托(delegate)和事件后,我正在尝试编写自己的代码: 我想创建一个带有可变参数模板的类,以指定函数的返回类型和可选参数。
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,所以我不明白哪里出了问题。
最佳答案
问题是您的 std::vector
存储函数指针。它不存储 std::bind
对象,不存储成员函数,不存储仿函数,也不存储 lambda。您正在尝试向其添加 lambda,因此失败。
如果你想存储任何类型的对象,它支持调用正确的参数和返回类型,你需要std::function
:
using FunType = std::function<Ret(Args...)>;
std::vector<FunType> vec;
顺便说一下,您可以通过完美转发您的 operator()
args 并在界面中复制您的 newElement
arg 并将其移动到 std 来改进您的解决方案::vector
。
关于C++ 模板化委托(delegate),如 Unity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31344009/