2014-09-18 56 views
2

类A定义的所有复制/移动的构造/分配如下被称为无复制/移动的构造/分配的同时初始化

A f(A a) { return a; } 
A g() { return A(); } 

main()功能是这样的:

int main() 
{ 
    A a1 = f(A());   // Move-construct 
    A a2 = std::move(a1); // Move-construct 
    A a3 (std::move(a2)); // Move-construct 
    A a4 (a1);    // Copy-construct 
    A a5 = a4;    // Copy-construct 
    a5 = f(A());   // Move constructor + Move assignment 
    a5 = a4;    // Copy assignment 
    a5 = g();    // Move assignment 
    A a6 = g();    // None!! Member-wise assignment (?) 
} 

可有人告诉我,为什么地球上没有任何一个构造函数和赋值操作符被调用a6? C++ 11文档的哪一部分描述了这种行为?

+5

http://en.wikipedia.org/wiki/Return_value_optimization – user1937198 2014-09-18 23:24:38

+2

“成员明智的分配”在这里不是一个选项。你提供了你自己的'operator ='。 (并且'T x = y;'不是任何赋值)。 – 2014-09-18 23:35:32

+0

正在调用默认的构造函数,然后编译器可以自由地删除副本。不是很好! – 2014-09-18 23:37:00

回答

3

这被称为复制省略和在C++标准,部分12.8 PT被描述31.

当满足特定条件时,一种实现被允许省略 类的复制/移动施工对象,即使为拷贝/移动操作选择的构造函数 和/或 对象的析构函数具有副作用。在这种情况下,执行对待 源和目标的省略复制/移动操作的简单地2种 指相同的对象(...)

情节描述以及不同的方式。其中一个之中的:

当尚未结合至参考 将被复制的一个临时的类对象/移动到具有相同的CV-不合格 类型的类对象时,复制/移动操作可以是通过直接构建 临时物体插入省略副本的目标省略/移动

为g()返回一个临时匿名对象(未绑定到参考),是被直接构建到目标A6。在你的例子中,使用了g的return语句的默认构造函数。