获取lambda的函数原型

时间:2017-11-25 05:44:40

标签: c++ templates

我正在创建通用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预选赛的情况下抓挠我的原型,但是我被卡住了。任何帮助将不胜感激。

1 个答案:

答案 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初始化它并返回它。