我有一个相当特殊的问题,因为我试图建立某种形式的一个编译器... 我想lambda表达式传递给模板函数是这样的:将任意的lambda表达式传递给函数?
template<class T>
delegate<T>* bind(std::function<T> func)
{
return nullptr;
}
所以,我现在可以请致电
bind([&](int a) { // do something });
...所以通常情况下,这不会是一个问题,因为std :: function能够捕获lambda。但是问题在于(让我们假设)我不知道或不想提供有关“T”究竟是什么的信息。它可以是任何函数签名,你也可以插入到std :: function <> ...
我还需要将此“推断”签名传回给我想返回的“委托”类,并且该委托类需要是一个指向class ...
现在我想出了这一点:
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”的实例,但这会使生成的代码不必要地复杂化。
顺便说一句,我使用的是最新的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;
}
请注意,您可能需要调整“常量”修饰您的需求。
从std :: function继承是不明智的想法。我敢打赌,它没有虚拟析构函数。 – chris
将'std :: function'作为参数传递出错了,但我不记得具体是什么。 –
现在我们不用担心这些细节,我只是想让这个模板参数推演起作用!这只是一个展示这个想法的片段。可能是我现在混淆了它。我的意思是C++ 11的目的是要通过引用来传递,但我可以记住像shared_ptr和std :: function可能是一个例外。 – thesaint