我有一个非常奇特的问题,因为我正在尝试创建某种编译器...... 我想将lambda表达式传递给模板化函数,如下所示:
template<class T>
delegate<T>* bind(std::function<T> func)
{
return nullptr;
}
所以我现在可以打电话了
bind([&](int a) { // do something });
...通常,这不会有问题,因为std :: function能够捕获lambda。但问题在于(让我们假设)我不知道或者不想提供关于“T”究竟是什么的信息。它可以是任何函数签名,您也可以插入到std :: function&lt;&gt; ...
中我还需要将此“推断”签名传递回我想要返回的“委托”类,并且该委托类需要是指向类的指针...
现在我想出了这个:
template<class T>
struct delegate : public std::function<T>
{
delegate(const std::function<T>& func) : std::function<T>(func) { }
delegate(const delegate<T>& func) { }
};
template<class T>
delegate<T>* bind(std::function<T>&& func)
{
return new delegate<T>(std::forward<std::function<T>>(func));
}
但是上面对“绑定”调用的例子失败了“失败的模板参数推断”。如何在调用“bind”时明确指定“T”参数(然后它至少可以工作)才能使其工作?
由于理论上我的编译器具有解决此问题的所有信息,我只能插入“T”的实例,但这会使生成的代码不必要地复杂化。
BTW,我正在使用最新的Clang编译器。
以下是最终解决方案:
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> struct get_signature<Ret(Mem::*)(Args...) const> {
typedef Ret type(Args...);
};
template<class T>
delegate<typename get_signature<decltype(&T::operator())>::type>* bind(T func)
{
return nullptr;
}
请注意,您可能需要根据需要调整“const”修饰符。
答案 0 :(得分:2)
首先,你完全搞砸了你的右值参考。您的转发根本不起作用。
其次,在某些情况下这是不可能的..对于某些函数对象,您可以通过将成员函数指针指向operator()
并检查它的签名来推断签名。但是对于其他人来说,他们会超负荷而且无法运作。
template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args>
struct get_signature<Ret(Mem::*)(Args...)> {
typedef Ret(Args...) type;
};
template<class T>
delegate<typename get_signature<&T::operator()>::type>* bind(T func)
{
return nullptr;
}
第三,std::bind
?