当我初始化一个 STL 容器时,例如list< vector<char> >
使用例如my_list.push_back(vector<char>(5000, 'T'))
,这是在构造后复制的吗?还是编译器会调用list< vector<char> >
自己内部的构造函数?
问问题
744 次
2 回答
7
在 C++03push_back
中定义为void push_back(const T& x);
. 这意味着您正在构造 avector
并且对此类时间的 const 引用正在传递给list
. 然后list
内部调用复制构造函数以存储此类元素的副本。
在 C++11 中有一个额外的定义,void push_back(T&& x);
它需要一个对你的 temporal 的右值引用vector
,并且会导致内部调用移动构造函数来初始化list
.
于 2011-09-29T19:56:02.647 回答
0
编译器很聪明。真聪明。在这种情况下,有一种称为“复制省略”的优化。C++ 标准允许编译器在使用临时对象初始化相同类型的对象时省略副本,并且该对象的复制构造函数没有副作用。
这与更流行的“好像”规则属于同一类优化。只要生成的程序的可观察行为与“好像”完全遵循标准一样,该规则允许编译器几乎可以摆脱它想要的任何东西。
这是一个示例程序。在带有 -O0 和 -O3 的 gcc 4.4.5 上,此代码导致打印“1”。我认为 GCC 在这里是错误的……一些编译器会输出“2”,表示发生了副本。这就是在尝试检测本应无法检测的行为时事情变得棘手的地方。在其中一个编译器中,唯一的判断方法是深入研究生成的程序集。
#include <iostream>
struct elision
{
explicit elision(int i) : v(i) {
}
elision(elision const ©) : v(copy.v+1) {
}
int v;
};
int main()
{
elision e(elision(1));
std::cout << e.v << std::endl;
return 0;
}
于 2011-10-01T01:03:58.733 回答