Bel*_*loc 6 c++ initialization language-lawyer copy-elision c++11
在下面的代码中s
,类的对象S
用于使用D
直接初始化初始化类的对象D d(s);
.转换函数S :: operator D()用于将对象s
转换为类型的临时对象D
.然后,gcc和clang都忽略了对move构造函数的显式调用D(&&)
,将这个临时对象移动到d
.查看实例.
#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);
}
Run Code Online (Sandbox Code Playgroud)
我基于以下理由对这个省略的正确性提出异议:
如果初始化是直接初始化,或者它是复制初始化,其中源类型的cv-nonqualified版本与目标类相同的类或派生类,则考虑构造函数.列举了适用的构造函数(13.3.1.3),并通过重载解析(13.3)选择最佳构造函数.调用所选的构造函数来初始化对象,初始化表达式或表达式列表作为其参数.如果没有构造函数适用,或者重载决策是不明确的,则初始化是错误的.
C++标准喜欢在完全不同的地方创建在一个地方定义的规则的例外.
复制/移动省略规则在12.8/31中规定.您的代码中有两个要删除的复制/移动操作.
第一个很简单:在内部operator D
,返回表达式中构造的临时值被移动到表示函数返回值的临时值.子弹3允许省略此举.
第二个是将临时函数返回值移动到d
对象.同样,子弹3允许省略.
- 当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动
归档时间: |
|
查看次数: |
299 次 |
最近记录: |