C++ gcc和clang都省略了下面代码段中对move构造函数的调用。这是正确的吗?

C++ gcc和clang都省略了下面代码段中对move构造函数的调用。这是正确的吗?,c++,c++11,initialization,language-lawyer,copy-elision,C++,C++11,Initialization,Language Lawyer,Copy Elision,在下面的代码中,类s的对象s用于通过直接初始化D(s)初始化类D的对象。转换函数S::operator D()用于将对象S转换为D类型的临时对象。然后,gcc和clang都省略了对move构造函数D(&&&)的显式调用,以将这个临时对象移动到D。看 #包括 结构D; 结构S{operator D();}; 结构D{ D(){} D(d & &){STD::CUT< P> C++标准喜欢在完全不同的地方创建对一个地方定义的规则的异常。 复制/移动省略规则在12.8/31中指定。代码中有两个复制/移

在下面的代码中,类
s
的对象
s
用于通过直接初始化
D(s)初始化类
D
的对象。转换函数S::operator D()用于将对象
S
转换为
D
类型的临时对象。然后,gcc和clang都省略了对move构造函数
D(&&&)
的显式调用,以将这个临时对象移动到
D
。看

#包括
结构D;
结构S{operator D();};
结构D{
D(){}

D(d & &){STD::CUT< P> C++标准喜欢在完全不同的地方创建对一个地方定义的规则的异常。 复制/移动省略规则在12.8/31中指定。代码中有两个复制/移动操作需要消除

第一个很简单:在
操作符D
中,返回表达式中构造的临时值被移动到表示函数返回值的临时值。项目符号3允许省略此移动

第二个是将临时函数返回值移动到
d
对象。同样,项目符号3允许省略

  • 当未绑定到引用(12.2)的临时类对象将被复制/移动到具有相同cv类型的类对象时,可以通过将临时对象直接构造到省略的复制/移动的目标中来省略复制/移动操作
#include <iostream>
struct D;
struct S{ operator D(); };

struct D{
    D(){}
    D(D&&) { std::cout << "move constructor" << '\n'; }
};

S::operator D() { std::cout << "conversion function" << '\n'; return D(); }

int main()
{
    S s;
    D d(s);
}