我正在创建一个通用 C++ EventEmitter
.它基于 Node.js EventEmitter :
template <typename ...Args>
int16_t EventEmitter::addListener(uint32_t eventId, std::function<void(Args...)> cb)
{
...
}
template <typename... Args>
void EventEmitter::emit(uint32_t eventId, Args... args)
{
...
}
它按预期工作(我可以使用不同的原型(prototype)注册监听器)。例如:
auto handler = [](int n) { ... };
listener.addListener(0, std::function<void(int)>(handler));
但我不想费心将整个监听器原型(prototype)输入到 std::function<...>
每次我添加一个(有些有超过 5 个参数),然后我决定创建一个宏:
#define STDFUNC(fn) std::function<decltype(fn)>(fn)
问题是当我尝试将它与 lambda 一起使用时:decltype(handler)
不是 void(int)
,它是 class lambda []void (int n)->void
相反,生成错误:
(Clang 3.7.1) -> error : implicit instantiation of undefined template 'std::_Get_function_impl<(lambda at ...
我绞尽脑汁想得到没有 lambda 限定符的原型(prototype),但我被卡住了。任何帮助将不胜感激。
最佳答案
这是一个为任意 lambda 生成函数对象的小程序:
#include <functional>
#include <type_traits>
template <typename R, typename... A>
class build_func_type
{
public:
using type = ::std::function<R(A...)>;
};
template <typename R, typename C, typename... A>
typename build_func_type<R, A...>::type mem_func_to_func( R(C::*)(A...) const)
{
return nullptr;
}
template <typename T>
decltype(mem_func_to_func(&T::operator ())) lambda_to_fp(T le)
{
using func_t = decltype(mem_func_to_func(&T::operator ()));
return func_t{le};
}
int test()
{
auto foo = [](int x) -> int { return x * x; };
auto ftype = lambda_to_fp(foo);
return ftype(5);
}
它使用函数 mem_func_to_func
自动推断 lambda 的 operator ()
的类型。然后它使用 build_func_type
模板从 lambda 的 operator ()
类型的组件中构建一个函数类型。我本可以在 build_func_type
中使用构造函数,并为此依赖 C++17 构造函数类型推导。
然后 lambda_to_fp
将采用一个 lambda,使用 mem_func_to_func
从指向 lambda 的 operator ()
的指针创建指向适当函数类型的指针> 成员函数。然后它创建一个适当类型的 ::std::function
,从函数指针的类型构造该类型。然后它用 lambda 对其进行初始化并返回它。
关于c++ - 获取 lambda 的函数原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47483000/