![](/img/trans.png)
[英]Why was the code required to have an accessible copy/move constructor even when copy-elision was permitted to happen?
[英]While doing copy-elision, the compiler doesn't consider the copy constructor in overload resolution, when the move constructor is deleted. Why?
我可以理解编译器在下面的代码中正在执行复制删除 ,因为在main()
所谓的copy-initialization
中并未调用copy和move构造函数。 参见现场示例 。
#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();
}
但是我不明白为什么删除如下所示的move构造函数时代码无法编译:
#include <iostream>
struct S {
S() = default;
S(const S&) { std::cout << "copy ctor" << '\n'; }
S(S&&) = delete;
};
int main() {
S s = S();
}
在这种情况下,我在§12.8/ 32(N4140)中找不到任何可能禁止使用或取消复制构造函数的内容 。 这句话在§12.8/ 32中引起了我的注意,似乎表明应在重载解决方案中考虑复制构造函数:
如果第一个重载解析失败或没有执行,或者如果所选构造函数的第一个参数的类型不是对该对象类型的右值引用(可能是cv限定),则再次执行重载解析,将对象视为左值。
编辑
从以下TC的评论之一中,我了解到,当要复制的对象由右值指定时,根据§12.8/ 32,编译器不会将复制构造函数视为复制的候选对象,即使是尽管仍然会删除该副本。 也就是说,最终的结果将是对象的构造s
与默认构造函数。 取而代之的是,在这种情况下,标准要求(在哪里?)代码格式错误。 除非我对这种方案的理解是完全错误的,否则对我来说没有任何意义。
这与复制省略或构造函数无关。 这只是过载解决方案。
如果我们有一对重载:
void f( T&& rv );
void f( const T& lv );
然后重载解析规则说f( T{} )
是f(T&&)
的更好匹配。
复制省略可以取消复制或移动,但仅当代码定义明确时(即使编译器选择不实施复制删除),也可以取消复制或移动。 您的代码定义不明确,因为它指定调用已删除的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.