我有一个非常奇特的问题,因为我正在尝试创建某种编译器...我想将 lambda 表达式传递给这样的模板化函数:
template<class T>
delegate<T>* bind(std::function<T> func)
{
return nullptr;
}
所以我现在可以打电话
bind([&](int a) { // do something });
...所以通常情况下,这不会是一个问题,因为 std::function 能够捕获一个 lambda。但这里的问题是(假设)我不知道或不想提供有关“T”到底是什么的信息。它可以是您也可以插入到 std::function<>... 的任何函数签名
我还需要将此“推断”签名传递回我想要返回的“委托”类,并且该委托类需要是指向类的指针......
现在我想出了这个:
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”的例子因“模板参数推导失败”而失败。如何在调用“bind”时无需显式指定“T”参数而使其工作(至少它可以工作)?
由于理论上我的编译器拥有解决此问题的所有信息,我可以只插入“T”的实例,但这会使生成的代码不必要地复杂化。
顺便说一句,我正在使用最新的 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”修饰符。