【发布时间】:2019-01-21 20:46:32
【问题描述】:
这个问题是关于 c++ 标准的措辞的。
所有编译器,我认为这是应该的,省略用于初始化对象 b 波纹管 (assembly here) 的复制构造函数:
struct B;
struct A{
operator B();
};
struct B{
B(const B&);
B(B&&);
};
void test(A a){
B b(a);
}
但是当我阅读标准时,我不明白为什么会发生这种省略(我的粗体)[dcl.init]/17.6.2:
否则,如果初始化是直接初始化,[...],则考虑构造函数。 枚举适用的构造函数([over.match.ctor]),并通过重载决议([over.match])选择最佳构造函数。 调用如此选择的构造函数来初始化对象,使用初始化表达式或表达式列表作为其参数。 如果没有构造函数适用,或者重载决议不明确,则初始化格式错误。
具体说是调用了构造函数。但是没有编译器会这样做。
我想我遗漏了一些东西或没有正确阅读标准。我应该如何阅读标准?
这与标准的前一段和下一段特别要求复制省略[dcl.init]/17.6.1形成对比:
如果初始化表达式是纯右值并且源类型的 cv 非限定版本与目标类是同一类,初始化表达式用于初始化目标对象。
和 [dlc.init]/17.6.3:
否则(即,对于剩余的复制初始化情况),可以从源类型转换为目标类型的用户定义转换 [...] 以初始化表达式作为参数调用所选函数; [...] 该调用用于直接初始化,根据上述规则,作为复制初始化目标的对象。
最后一句将我送回 [dcl.init]/17.6.1,这也意味着复制省略。
【问题讨论】:
-
似乎等同于copy_elision的示例
-
@Jarod42 我认为此页面上的所有示例都与 [dcl.init]/17.6.1 匹配,而不是困扰我的第 17.6.2 段。
-
您希望编译器将
a对象转换为临时B对象,然后在构造b期间将该临时对象复制到b?它使用b来存储a转换为B的返回值。 -
@1201ProgramAlarm 这是我在标准中读到的。根据我的阅读,复制省略不应该发生。
标签: c++ initialization language-lawyer c++17 copy-elision