C++ 为什么这个动作不起作用

C++ 为什么这个动作不起作用,c++,c++11,move,copy-constructor,move-semantics,C++,C++11,Move,Copy Constructor,Move Semantics,我有以下代码片段。有人知道为什么主函数中的所有情况都不调用这个move构造函数吗?为什么它要编译呢?外派接线员是私人的吗?链接如下: #包括 #包括 甲级{ 公众: A(国际一){ std::cout您所看到的被称为拷贝省略,并记录在12.8.31中 A makeA(){ A a(3); return a; } A b1(makeA()) ; A b2 = makeA(); 这里,makeA中的a局部变量直接放置在makeA的返回值中,而makeA的临时返回值则直接放置在b1

我有以下代码片段。有人知道为什么主函数中的所有情况都不调用这个move构造函数吗?为什么它要编译呢?外派接线员是私人的吗?链接如下:

#包括
#包括
甲级{
公众:
A(国际一){

std::cout您所看到的被称为拷贝省略,并记录在12.8.31中

A makeA(){
    A a(3);
    return a;
}

A b1(makeA()) ;
A b2 = makeA();
这里,
makeA
中的
a
局部变量直接放置在
makeA
的返回值中,而
makeA
的临时返回值则直接放置在
b1
b2
的存储器中(一行两个副本省略)

使用
A(3)
创建的临时文件直接在
b3
b4
中构造(一个副本省略)

当满足某些条件时,允许实现省略类的复制/移动构造 对象,即使为复制/移动操作选择了构造函数和/或为对象选择了析构函数 有副作用。在这种情况下,实现处理省略的复制/移动的源和目标 操作为引用同一对象的两种不同方式,并销毁该对象 在两个对象在没有优化的情况下会被销毁的时间较晚时发生。122 这种复制/移动操作的省略称为复制省略,在以下情况下是允许的 可组合使用以消除多个副本):

这是
b1
b2
案例的第一部分:

  • 在具有类返回类型的函数中的return语句中,当表达式是 具有相同cv的非易失性自动对象(函数或catch子句参数除外)- 不合格类型作为函数返回类型,复制/移动操作可以通过构造 自动对象直接输入函数的返回值
这是
b1
b2
案例的第二部分,以及
b3
b4
案例的整个部分:

  • 复制/移动未绑定到引用(12.2)的临时类对象时 对于具有相同cv类型的类对象,可以通过 将临时对象直接构造到省略的复制/移动的目标中

还有另外两种允许复制省略的情况与抛出和捕获异常有关。

复制分配操作符甚至都不参与其中,请不要将
=
标记的存在与分配混淆(例如,
b1=b2;

虽然复制初始化要形成良好的格式,需要可以访问复制或移动构造函数,但编译器可以自由地省略它并直接初始化对象。对于每个构造函数,哪种构造函数都有细微的差别,请阅读更多有关此方面的信息


如果您使用的是GCC,请尝试使用
-fno-elide构造函数编译,并查看差异。

这里可能就是这种情况,嗯……可能是重复的,所以它认为->
A b3=A(3);
-->A(3)是临时的,因此移动构造函数将匹配?@Gabriel:是的:临时的是右值,因此可以绑定到右值引用。特别是,它可以直接传递给移动构造函数。如果没有复制省略,它将是临时的移动构造。但是,由于复制省略
b3
A b3(3);
(至少在你的编译器中是这样)。我认为,在OP的情况下,直接初始化和复制初始化之间没有区别。@user1131467在OP的情况下不是,不,但我不想知道。当然,它只在类和“源类型的cv非限定版本与目标类不是同一类,也不是目标类的派生类”。在这种情况下,复制和直接初始化是有区别的。@user1131467,还有
显式
构造函数。@Gabriel OP=original post/poster。
 std::pair<int,A> a(3,A(3));
A makeA(){
    A a(3);
    return a;
}

A b1(makeA()) ;
A b2 = makeA();
A b3 = A(3);
A b4(A(3));
A b1(makeA()) ;  // direct initialization
A b2 = makeA();  // copy-initialization
A b3 = A(3);     // copy-initialization
A b4(A(3));      // direct initialization