使用函数模板而不是通用lambda?

Kno*_*abe 8 c++ lambda generic-lambda c++14

我可以写一个函数模板:

template<typename T>
void f1(T parameter) { ... }
Run Code Online (Sandbox Code Playgroud)

但是在C++ 14中,我还可以创建一个通用的lambda:

auto f2 = [](auto parameter) { ... };
Run Code Online (Sandbox Code Playgroud)

f1可以参考我T直接.在内部f2,没有T可以参考,但我可以使用decltype以下方式获得相同的效果:

auto f2 = [](auto parameter)
          {
            using T = decltype(param);
            ...
          };
Run Code Online (Sandbox Code Playgroud)

通用lambda的一个优点是我可以完美地转发它.我不能用功能模板做到这一点:

template<typename T>
void fwdToG(T&& param) { g(std::forward<T>(param)); }

fwdToG(f1);        // error!
fwdToG(f2);        // okay
Run Code Online (Sandbox Code Playgroud)

是否存在使用函数模板比​​使用通用lambda更好的情况?

Yak*_*ont 4

函数template允许重载具有相同名称的其他函数,并且可以通过 ADL 调用它们。通用 lambda 是具有重载的对象(),因此两者都不起作用。

您可以非常轻松地将函数重载集传递给对象:

 struct foo_overload_set_t {
   template<class...Ts>
   constexpr auto operator()(Ts&&...ts)const{ return foo(std::forward<Ts>(ts)...); }
 };
Run Code Online (Sandbox Code Playgroud)

使用 RVO 可以完全优化(零开销),并且可以将整个重载集的实例传递给算法。您还可以在使用时使用 lambda 来执行此操作,该 lambda 可以由宏生成。

通过多一点样板,上述重载集还可以支持转换为任何调用兼容的函数指针,而 lambdatemplate和 lambda 解决方案都不支持这种转换(lambda 要求签名匹配一个版本,而不是兼容性)。