为什么一个人永远不会使用汽车&&对于局部变量?

时间:2014-10-14 07:50:26

标签: c++ c++11 auto c++14 perfect-forwarding

虽然T&&与模板一起用作转发参考通用参考(正如Scott Meyers所说的那样),但我看到一些博客使用{{1在代码示例中。我认为auto&&本身就足够了,但是,CppCon 2014 says中的Herb Sutter:永远不要将auto用于局部变量

为什么?

看到所有回复,我觉得我应该问对方。尽管有一般编码指南,但是使用auto& amp;&amp ;;在函数体内部,用于代码的正确性和可维护性。

2 个答案:

答案 0 :(得分:4)

有些情况下,您需要auto&&作为本地人,请考虑:

vector<bool> vb { true, false, true };
for( auto&& b : vb )
    b = !b;

这里,一个汽车&amp;不会这样做。 (如果vector<bool>是专门的)

但是,您通常使用&&和类型扣除的原因
(即转发参考)是因为你不知道或不关心 确切的类型,你只是要转发它。

术语&#39;通用参考&#39;有点误导,你不应该使用
它普遍,因此它的名称改为&#39;转发参考&#39;

请注意,&&未与类型推导一起使用的是右值引用,不同的是 事情一共。

答案 1 :(得分:-3)

如果您想使用range-for循环来修改vector<bool>的内容,我会承认有一个足够好的案例。但是,我建议阅读"On vector<bool>" by Howard Hinnant - 负责右值参考的人。

除了这种失常之外,没有激励性的例子来显示局部变量的auto&&用法。 auto&&的每个局部变量用法都是滥用(Sutter实际上是指),除了通用lambda。通过激励我的意思是你不能在没有auto&&的情况下编写最佳和正确的代码(没有隐式转换等)。您可以使用它只是因为您正在等待使用核武器来杀死鼠标。让我们考虑一些看似相关的案例。

  1. 基于范围的语句 在§6.5.4中定义为等同于:

    {
        auto && __range = range-init;
        for ( auto __begin = begin-expr, __end = end-expr;
              __begin != __end; ++__begin )
        {
            for-range-declaration = *__begin;
            statement
        }
    }
    

    现在这纯粹是理论上的。让我们做一个思想实验并说编译器会这样做。编译器并不以高级实现而闻名。即使他们这样做,你确定你可以得到一个表达式range-init来统治它们。

  2. 在多个接口上转发转发引用的我自己似是而非的论点。如果您只想转发为什么需要auto&&命名别名。刚前进。

  3. 如果函数返回通用引用,该怎么办?真的吗?不允许在返回类型上重载。您可以通过模板完成它。但是,在相关问题中,示例将T作为模板参数传递,并返回T。如果您说T可以是右值或左值,我想使用auto&&,那么您就会失忆。

  4. 继续3,即使你假设你不知道你是从黑匣子里得到T还是T&(我会避免这样的盒子)你没有任何有意义的事情可以做到推断它是左值还是左值。如果你想向前迈进。

  5. for循环问题。让我概括一下。考虑一般用例,例如for( auto x : {a, b , c})for(auto x : getVector())或类似情况。您想使用for(auto&& b : vb),因为vb可能是临时的,您可能还想修改临时内容。在我有限的智慧中,我不明白你为什么要修改临时矢量或列表的内容。您可以继续提出类似下一项可能取决于修改的先前值等的参数,但是您可以在没有auto&&的情况下提出最佳解决方案。我个人认为修改临时内容而不将其绑定到const T&应该是非法的。

  6. 可变参数模板参数。我梦见如果我需要从var...剥离第一个参数,我可能想要使用auto&&T&&。我不认为即便如此。如果可能存在合理的案例,请告诉我。

  7. 我希望auto&&绑定一些内容。然后在for循环中使用它。只需在里面使用它就可以循环使用。

  8. 如果你真的提出了一个足够好的案例,除了lambdas之外的杀手论证:如果没有确定或修改为TT& ,你就无法写出足够的行数。否则,因为你想编写最佳代码,你会有代码膨胀...对于你写的每一行,你必须检查rvalue是否执行此操作,如果rvalue这样做。最好在开始时使用类型特征来确定r / l值。

  9. 如果遇到任何问题,请添加新的似是而非的好用例。