在基于 for 循环的范围内复制省略
Copy elision in range based for loops
我有以下代码:
#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
我的问题是为什么要打印 Copied?调用 push_back(A())
时为什么没有删除副本?在 for (A a: vec)
行中,为什么没有删除副本?
我正在使用以下命令进行编译:
sh-4.3# g++ -std=c++11 -O3 -o main *.cpp
很简单,因为在这种情况下没有允许复制省略的规则。
通常只在从函数返回值时,或在复制初始化时才允许。在所有其他情况下,如果副本有副作用(例如您的 I/O),则禁止复制省略。
标准制定如此宽松的规则,以至于 任何 副本都可能被禁止,无论副本的副作用是什么:你将失去任何能力确定性地合理化您的程序。此外,在一般情况下,您的编译器确定这样做是安全的在计算上是不可行的。
仅针对循环或仅针对不使用循环值的循环的异常在逻辑上是任意的。
我有以下代码:
#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
我的问题是为什么要打印 Copied?调用 push_back(A())
时为什么没有删除副本?在 for (A a: vec)
行中,为什么没有删除副本?
我正在使用以下命令进行编译:
sh-4.3# g++ -std=c++11 -O3 -o main *.cpp
很简单,因为在这种情况下没有允许复制省略的规则。
通常只在从函数返回值时,或在复制初始化时才允许。在所有其他情况下,如果副本有副作用(例如您的 I/O),则禁止复制省略。
标准制定如此宽松的规则,以至于 任何 副本都可能被禁止,无论副本的副作用是什么:你将失去任何能力确定性地合理化您的程序。此外,在一般情况下,您的编译器确定这样做是安全的在计算上是不可行的。
仅针对循环或仅针对不使用循环值的循环的异常在逻辑上是任意的。