像Unity一样的c++模板化委托
C++ Templated Delegates like Unity
看到Unity的委托和事件后,我试图编写自己的代码:我想用可变模板创建一个类,指定函数的返回类型和可选参数。
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()
参数并复制界面中的newElement
参数并将其移动到std::vector
中来改进您的解决方案。
您的委托只接受函数指针。lambda不是函数指针。但是,您尝试的lambda没有捕获任何内容。这意味着它可以通过一些魔法转换为函数指针:
MyDelegate<void, int> delegate1;
delegate1 += +[](const int a)->void{std::cout << a << std::endl; };
↑↑↑
然而,一旦你想允许有成员变量的函子,额外的+
将不起作用:
delegate1 += +[x](const int a) { ... }; // error: no match for operator+
在这一点上,你肯定要使用TartanLlama的std::function
的建议。
@TartanLlama的右边,std::函数就是你需要的。
调用循环可以折叠为for (auto handler : vec) handler(args...);
相关文章:
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- 堆栈和队列是否像C++中的数组一样传递?
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 我们可以将集合的值存储在变量中吗?就像我们可以将数组的值存储在变量中一样
- 我如何在C++像在 Python 中一样实现 f 字符串?
- 自制的上衣:看起来一样,但不完全相同
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 如何像在 C++ 中处理数组一样对 .txt 文件中的字符进行寻址?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 像 CPP 中的控制台一样的应用程序
- 为什么C++中没有常量引用,就像常量指针一样?
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- 有没有像给定的一样的 std::optional_function
- Java 是否像C++模板一样具有泛型推论?
- 记忆栅栏和记忆屏障是一样的吗
- 对象作为参数传递,就好像我们正在传递构造函数值一样
- 像自定义类一样构造的指针(内置类型)如何工作?
- JavaScript箭头函数:我们能否像C ++ lambdas一样捕获值