1

我有以下代码:

#include <iostream>
#include <vector>

using namespace std;

class A {
    public:
    A() {    
    }

    A(const A &a) {
        cout << "Copied!" << endl;
    }
};

int main()
{
   vector<A> vec;
   vec.push_back(A());
   vec.push_back(A());
   vec.push_back(A());
   cout << "Hello World" << endl;

   for (A &a: vec) {
       cout << "loop1" <<endl;
   }
   for (A a: vec) {
       cout << "loop2" <<endl;
   }

   return 0;
}

我运行了这个程序并打印了:

Copied!
Copied!
Copied!
Hello World
loop1
loop1
loop1
Copied!
loop2
Copied!
loop2
Copied!
loop2

我的问题是为什么要复印?调用时push_back(A())为什么没有省略副本?在行for (A a: vec)中为什么没有省略副本?

我正在使用以下命令进行编译: sh-4.3# g++ -std=c++11 -O3 -o main *.cpp

4

1 回答 1

4

很简单,因为在这种情况下没有允许复制省略的规则。

通常仅在从函数返回值或复制初始化时才允许。在所有其他情况下,如果副本具有副作用(例如您的 I/O),则禁止复制省略。

对于标准来说,将规则制定得如此宽松以至于无论副本的副作用是什么都可能被禁止,这将是疯狂的:您将失去任何确定性地合理化您的程序的能力。此外,在一般情况下,您的编译器无法确定这样做是否安全,这在计算上是不可行的。

仅用于循环或仅用于不使用循环值的循环的例外将是不合逻辑的任意性。

于 2015-02-16T11:29:22.283 回答