我正在创建通用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)
{
...
}
它按预期工作(我可以使用不同的原型注册听众)。例如:
auto handler = [](int n) { ... };
listener.addListener(0, std::function<void(int)>(handler));
但是,每次添加一个(有些参数超过5个)时,我都不想打扰整个监听器原型到std::function<...>
,然后我决定创建一个宏:
#define STDFUNC(fn) std::function<decltype(fn)>(fn)
问题是当我尝试将它与lambdas一起使用时:decltype(handler)
不是void(int)
,而是class lambda []void (int n)->void
而是产生错误:
(Clang 3.7.1) - &gt;错误:未定义模板的隐式实例化 &#39; std :: _ Get_function_impl&lt;(lambda at ...
我在没有lambda预选赛的情况下抓挠我的原型,但是我被卡住了。任何帮助将不胜感激。
答案 0 :(得分:1)
这是一个为任意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
将使用mem_func_to_func
使用lambda来从指向lambda operator ()
成员函数的指针创建指向相应函数类型的指针。然后它创建一个适当类型的::std::function
,从函数指针的类型构造该类型。然后用lambda初始化它并返回它。