【问题标题】:Can the use of C++11's 'auto' deteriorate performance or even break the code?使用 C++11 的“自动”会降低性能甚至破坏代码吗?
【发布时间】:2016-07-16 21:31:24
【问题描述】:

此问题与现有问题“Can the use of C++11's 'auto' improve performance?”相反

One of the answers 对那个问题表示auto 的使用不仅可以产生积极影响,也可以产生消极影响。

我认为我们需要一个单独的问题,答案集中在auto 的那一侧。

【问题讨论】:

  • auto 盲目地搜索和替换所有变量声明符几乎肯定会破坏您的代码。想想cv 和 ref 限定符。普通的auto通常cv 或引用限定的auto 不同。 .... 想想auto 不会进行的转换

标签: c++ c++11 lazy-evaluation auto


【解决方案1】:

auto 在变量声明+初始化行没有转换。但是,如果这种转换无论如何都必须发生,最好在初始化期间发生一次,而不是多次发生。

struct X {
    ...
};

struct Y {
    operator X() const;
    ...
};

Y foo(); // maybe, originally its return type was X but later was changed to Y
void bar(const X& );

const auto x = foo();           // <-- conversion not happening here
                                //
for ( int i = 0; i < 100; ++i ) //
    bar(x);                     // <-- silently rages here

auto 与惰性求值(现实世界中的example 1example 2)结合使用时,这种延迟转换可能会破坏代码:

class Matrix { ... };

class MatrixExpression {
    ...
    operator Matrix() const;
};

MatrixExpression operator+(const Matrix& a, const Matrix& b);
std::ostream& operator(std::ostream& out, const Matrix& m);

Matrix a = ...;
Matrix b = ...;
auto c = a + b; // evaluation of the matrix addition doesn't happen here
a[0][0] += 1;
std::cout << c; // matrix addition is evaluated here, using the new state of 'a'

【讨论】:

  • 它还会影响重载解析和模板实例化。如果long 变为autolong x = 1; cout &lt;&lt; sizeof(x); 会改变行为。作为一个特例,int* p = 0: 如果您将其重写为auto p = 0;,则会显着改变其含义
【解决方案2】:

您的问题标题指定“表现”。

auto 是一个编译时构造,它允许将自身替换为推导类型。它的使用不会产生不同的机器指令,而不是你手写它推导出的类型名。

问题在于,在管理性能时,类型规范和强制转换通常是至关重要的,auto 可以隐藏领先的程序员说出与他们本意不同的内容:

std::vector<std::array<BigStruct, 10000>>& f();
auto va = f();  // copy
for (auto v: va) {  // copies
    // ...
}

如果程序员写过:

std::vector<std::array<BigStruct, 10000>> va = f();

for (std::array<BigStruct, 10000> v : va)

他们会意识到他们是按值指定的。但是std::array&lt;BigStruct, 10000&gt;auto 在这里推导出的,在这些情况下,它转化为按值。

人们放下了警惕,忘记了auto 推断出 type,它不包括 ref 限定。

auto& va = f();  // reference
for (auto& v : va) {  // references

这里有性能影响,但不是由auto 引起的,而是(意外)显式指定副本的副作用。

auto 不代表 the same as this,而是代表 an instance of this

auto va = f();   // an instance-of what f returns, thus a copy.
auto& va = f();  // a reference to an instance-of, thus by reference.

【讨论】:

    【解决方案3】:

    无论何时使用大括号初始化,auto 对所有类型声明的盲目搜索和替换都会让人头疼:

    class Point
    {
    public:
        Point (int x1, int y1) { x = x1; y = y1; }
    private:
        int x, y;
    };      
    
    int main() 
    {
        Point p{5, 6};
        auto q{5, 6}; // Error. Uniform initialization is not REALLY uniform
    }
    

    变量 p 的第一个声明被正确推断为对接受两个整数的构造函数的调用。但是 auto 变量 q 搜索需要 std::initializer_list&lt;int> 的构造函数,因此无法编译。

    【讨论】:

      猜你喜欢
      • 2013-08-30
      • 1970-01-01
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      相关资源
      最近更新 更多