c – gcc和clang都在下面的代码片段中忽略了对move构造函数的调用.它是否正确?

前端之家收集整理的这篇文章主要介绍了c – gcc和clang都在下面的代码片段中忽略了对move构造函数的调用.它是否正确?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在下面的代码中,类S的对象s用于使用直接初始化D d(s);来初始化类D的对象.转换函数S :: operator D()用于将对象转换为D类型的临时对象.然后,gcc和clang都忽略对移动构造函数D(&&)的显式调用,以移动它临时对象进入d.见 live example.
#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);
}

我基于以下理由对这个省略的正确性提出异议:

>这个案例在§8.5/ 16(N3337)的第一个子项目中有所涉及,它没有提及elision.

If the initialization is direct-initialization,or if it is
copy-initialization where the cv-unqualified version of the source
type is the same class as,or a derived class of,the class of the
destination,constructors are considered. The applicable constructors
are enumerated (13.3.1.3),and the best one is chosen through overload
resolution (13.3). The constructor so selected is called to initialize
the object,with the initializer expression or expression-list as its
argument(s). If no constructor applies,or the overload resolution is
ambiguous,the initialization is ill-formed.

>请注意,下一个子项目明确提到了省略的可能性.
>对move构造函数调用是显式的.怎么可以省略?

解决方法

C标准喜欢在完全不同的地方创建在一个地方定义的规则的例外.

复制/移动省略规则在12.8 / 31中规定.您的代码中有两个要删除的复制/移动操作.

第一个很简单:在运算符D中,返回表达式中构造的临时值被移动到表示函数返回值的临时值.子弹3允许省略此举.

第二个是将临时函数返回值移动到d对象.同样,子弹3允许省略.

  • when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type,the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
原文链接:https://www.f2er.com/c/239560.html

猜你在找的C&C++相关文章