C++ 当我初始化一个C++;复制构造函数调用的是容器(如std::list)?

C++ 当我初始化一个C++;复制构造函数调用的是容器(如std::list)?,c++,copy-constructor,move-constructor,C++,Copy Constructor,Move Constructor,当我初始化一个STL容器,例如一个列表时,使用例如my\u list.push\u back(vector(5000,'T'))这是在构建后复制的吗?或者编译器是否在列表自身内部调用构造函数?在C++03中push\u back定义为void push\u back(const T&x)。这意味着您正在构造一个向量,并且对这种时态的常量引用被传递到列表。然后,列表在内部调用复制构造函数以存储此类元素的副本 在C++11中,void push_-back(T&&x)有一个额外的定义,它对时态向量进

当我初始化一个STL容器,例如一个
列表
时,使用例如
my\u list.push\u back(vector(5000,'T'))
这是在构建后复制的吗?或者编译器是否在
列表
自身内部调用构造函数?

在C++03中
push\u back
定义为
void push\u back(const T&x)。这意味着您正在构造一个
向量
,并且对这种时态的常量引用被传递到
列表
。然后,
列表
在内部调用复制构造函数以存储此类元素的副本


在C++11中,
void push_-back(T&&x)有一个额外的定义,它对时态
向量进行右值引用,并将导致在内部调用move构造函数来初始化
列表持有的副本,编译器是智能的。真聪明。在这种情况下,有一个优化叫做“复制删除”。C++标准允许编译器在临时对象被用来初始化同一类型的对象时,省略拷贝,并且该对象的复制构造函数没有副作用。p>
这与更流行的“好像”规则属于同一类优化。这条规则允许编译器几乎可以随心所欲,只要生成的程序的可观察行为与“仿佛”完全遵循标准的行为相同

下面是一个示例程序。在gcc 4.4.5中,同时使用-O0和-O3时,此代码会导致打印“1”。我认为GCC在这里是错误的。。。某些编译器将输出“2”,表示发生了复制。这就是在试图检测到本应无法检测到的行为时变得棘手的地方。在其中一个编译器中,唯一的判断方法是深入研究生成的程序集

#include <iostream>

struct elision
{
    explicit elision(int i) : v(i) {
    }

    elision(elision const &copy) : v(copy.v+1) {
    }

    int v;
};

int main()
{
    elision e(elision(1));
    std::cout << e.v << std::endl;
    return 0;
}
#包括
结构省略
{
显式省略(inti):v(i){
}
省略(省略常量和副本):v(副本v+1){
}
INTV;
};
int main()
{
省略e(省略(1));

STD::换句话说,微软Visual C++ 2010和UP不复制.@ UNIXMAN83:这不是编译器定义的,而是通过标准库的实现。我理解VC++ 10实现了R值引用,所以我希望它能做一个移动构造而不是复制构造。@ UnxMn83:VC++ 9当然可以。复制复制是对IF规则的唯一例外…编译器不需要考虑复制构造函数的副作用,所以1和2都是有效的输出。我宁愿安全地运行,并等待移动构造函数成为主流。