我可以写一个功能模板:
template<typename T>
void f1(T parameter) { ... }
但是在C ++ 14中,我还可以创建一个通用的lambda:
auto f2 = [](auto parameter) { ... };
在f1
内我可以直接引用T
。在f2
内,没有T
可以引用,但我可以使用decltype
获得相同的效果:
auto f2 = [](auto parameter)
{
using T = decltype(param);
...
};
通用lambda的一个优点是我可以完美地转发它。我无法使用功能模板:
template<typename T>
void fwdToG(T&& param) { g(std::forward<T>(param)); }
fwdToG(f1); // error!
fwdToG(f2); // okay
是否存在使用函数模板比使用泛型lambda更好的情况?
答案 0 :(得分:4)
函数template
允许重载具有相同名称的其他函数,并通过ADL调用它们。通用lambda是具有重载()
的对象,因此都不起作用。
您可以非常轻松地将函数重载集传递给对象:
struct foo_overload_set_t {
template<class...Ts>
constexpr auto operator()(Ts&&...ts)const{ return foo(std::forward<Ts>(ts)...); }
};
具有RVO的可以完全优化(零开销),并且可以将整个重载集的实例传递给算法。您也可以在使用点使用lambda来执行此操作,该lambda可以由宏生成。
如果有更多的样板,上面的重载集也可以支持转换到任何调用兼容的函数指针,template
和lambda解决方案都不支持(lambda要求签名匹配一个版本,而不是兼容性)。