C++14 为我们带来了泛型 lambda(generic lambda),可以在参数声明中使用 auto。这个特性的实现原理也不难想到:将 lambda 生成类的 operator() 变为一个模板函数即可。例如,下面的 lambda 函数在编译中产生的类可能形如:
auto f = [](auto x){ return func(normalize(x)); };
↓
class SomeCompilerGeneratedClassName {
public:
template // see Item 3 for
auto operator()(T x) const // auto return type
{ return func(normalize(x)); }
... // other closure class functionality
};
如果 normalize 函数对左值和右值的处理方式不同,那么以上的写法就是欠妥的,因为不管外部调用 f 时的入参是左值还是右值,以 x 调用 normalize 调用的永远是左值版本(见 Item 23),这正是我们为什么需要用 std::forward 进行完美转发。
但这里有一个问题:std::forward 的调用形式是 std::forward 如果你对万能引用的原理:引用折叠(见 Item 28)比较熟悉,看到这里可能会有些心存疑虑:假设入参类型为 Widget,当入参为右值 Widget&& 时,对于模板函数,std::forward 让我们通过源码来考察。std::forward 的实现如下: 当入参为 Widget&& 时,引用折叠发生前后分别为: 对比会发现这与 T 的类型是 Widget 时完全相同,所以,如此调用是没有问题的。 当然,以上讨论也都适用于可变参数:
auto f = [](auto&& x) { // 注意万能引用的形式为auto&&
return func(normalize(std::forward
template
Widget&& && forward(Widget& param)
{
return static_cast
auto f = [](auto&&... params) {
return func(normalize(std::forward
总结
对 auto&& 参数使用 decltype 以转发它们。(复读标题ww)



