C++ 模板化委托(delegate),如 Unity

标签 c++ templates delegates variadic

在看到 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;

Demo

顺便说一下,您可以通过完美转发您的 operator() args 并在界面中复制您的 newElement arg 并将其移动到 std 来改进您的解决方案::vector

关于C++ 模板化委托(delegate),如 Unity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31344009/

相关文章:

c++ - C++ 的模块概念

c++ - 具有重载的显式模板函数特化 : Why would you do it?

c++ - 类型相关模板名称

c++ - 优化switch的模板替换

C# 我应该阻止一个事件被两次取消 Hook 吗?

c++ - 检查 STL 中的空交集

c++ - 我怎样才能捕捉到 ctrl-c 事件?

c++ - Google Benchmark 自定义设置和拆卸方法

ios - 数据从 watch 发送到手机后未调用 Swift 3 XML 解析委托(delegate)

ios - 自定义委托(delegate)为零