Fra*_*uet 6 c++ language-lawyer copy-elision c++14
我可以理解编译器正在下面的代码中执行copy-elision,因为复制和移动构造函数不会在所谓的copy-initializationdone in中调用main().查看实例.
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) { std::cout << "move ctor" << '\n'; }
};
int main() {
S s = S();
}
Run Code Online (Sandbox Code Playgroud)
但是当我删除移动构造函数时,我无法理解为什么代码不能编译,如下所示:
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) = delete;
};
int main() {
S s = S();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我在§12.8/ 32(N4140)中找不到任何可能禁止使用或省略复制构造函数的内容.这是在§12.8/ 32中引起我注意的句子,这似乎表明复制构造函数应该在重载决策中被考虑:
如果第一个重载决策失败或未执行,或者所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv-qualified),则再次执行重载决策,将对象视为左值.
编辑
从以下TC的评论之一,我理解当要复制的对象由右值指定时,编译器根据§12.8/ 32,不认为复制构造函数是副本的候选者,甚至虽然副本无论如何都会被删除.也就是说,最终结果将是s使用默认构造函数构造对象.相反,在这种情况下,标准要求(在哪里??)代码是不正确的.除非我对这个方案的理解完全错误,否则对我来说没有任何意义.
这与复制省略或构造函数无关;这只是重载解析。
如果我们有一对重载:
void f( T&& rv );
void f( const T& lv );
Run Code Online (Sandbox Code Playgroud)
那么重载解析规则表明f( T{} )更适合f(T&&).
复制省略可以省略复制或移动,但前提是代码定义良好(即使编译器选择不实现复制省略)。您的代码定义不明确,因为它指定调用已删除的函数。
| 归档时间: |
|
| 查看次数: |
209 次 |
| 最近记录: |