8

我可以写一个函数模板:

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 更好的情况?

4

1 回答 1

4

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

您可以很容易地将函数重载集传递给对象:

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

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

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

于 2014-04-05T03:42:58.227 回答