简体   繁体   English

在进行复制删除时,当删除移动构造函数时,编译器不会将复制构造函数视为处于过载解析状态。 为什么?

[英]While doing copy-elision, the compiler doesn't consider the copy constructor in overload resolution, when the move constructor is deleted. Why?

I can understand the compiler is doing copy-elision in the code below, as the copy and move constructors are not invoked in the so called copy-initialization done in main() . 我可以理解编译器在下面的代码中正在执行复制删除 ,因为在main()所谓的copy-initialization中并未调用copy和move构造函数。 See live example . 参见现场示例

#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(); 
}

But I can't understand why the code doesn't compile when I delete the move constructor as below: 但是我不明白为什么删除如下所示的move构造函数时代码无法编译:

#include <iostream>
struct S {
    S() = default;
    S(const S&) { std::cout << "copy ctor" << '\n'; }
    S(S&&) = delete;
};

int main() {
    S s = S(); 
}

I can't find anything in §12.8/32 (N4140) that could disallow the copy constructor from being used or elided, in this case. 在这种情况下,我在§12.8/ 32(N4140)中找不到任何可能禁止使用或取消复制构造函数的内容 This is the sentence that called my attention in §12.8/32, which seems to indicate that the copy constructor should have been considered in the overload resolution: 这句话在§12.8/ 32中引起了我的注意,似乎表明应在重载解决方案中考虑复制构造函数:

If the first overload resolution fails or was not performed, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object's type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. 如果第一个重载解析失败或没有执行,或者如果所选构造函数的第一个参数的类型不是对该对象类型的右值引用(可能是cv限定),则再次执行重载解析,将对象视为左值。

Edit 编辑

From one of the comments by TC below, I understand that when the object to be copied is designated by an rvalue, the compiler, according to §12.8/32, doesn't consider the copy-constructor as a candidate for the copy, even though the copy would be elided anyway. 从以下TC的评论之一中,我了解到,当要复制的对象由右值指定时,根据§12.8/ 32,编译器不会将复制构造函数视为复制的候选对象,即使是尽管仍然会删除该副本。 That is, the end result would be the construction of the object s with the default constructor. 也就是说,最终的结果将是对象的构造s与默认构造函数。 Instead, in this situation the Standard mandates (where??) the code to be ill-formed. 取而代之的是,在这种情况下,标准要求(在哪里?)代码格式错误。 Unless my understanding of this scheme is completely wrong, that doesn't make any sense to me. 除非我对这种方案的理解是完全错误的,否则对我来说没有任何意义。

This is nothing specific to do with copy elision or constructors; 这与复制省略或构造函数无关。 it is just overload resolution. 这只是过载解决方案。

If we have a pair of overloads: 如果我们有一对重载:

void f( T&& rv );
void f( const T& lv );

then the overload resolution rules say that f( T{} ) is a better match for f(T&&) . 然后重载解析规则说f( T{} )f(T&&)的更好匹配。

Copy elision can elide a copy or move, but only when the code is well-defined ( even if the compiler chooses not to implement copy elision). 复制省略可以取消复制或移动,但仅当代码定义明确时(即使编译器选择不实施复制删除),也可以取消复制或移动。 Your code is not well-defined, because it specifies to call a deleted function. 您的代码定义不明确,因为它指定调用已删除的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么即使允许复制删除操作,代码也需要具有可访问的复制/移动构造函数? - Why was the code required to have an accessible copy/move constructor even when copy-elision was permitted to happen? 使用移动时不会发生复制省略 - Copy-elision doesn't happen when using move 复制初始化:为什么即使关闭复制省略也没有调用移动或复制构造函数? - copy initialization : why move or copy constructor was not called even if copy-elision is turned off? C++:右值引用构造函数和复制省略 - C++: rvalue reference constructor and copy-elision 移动构造函数与复制省略 - Move constructor vs Copy elision 为什么标准不将模板构造函数视为复制构造函数? - Why doesn't the standard consider a template constructor as a copy constructor? 如何执行复制省略,为什么它不适用于删除的复制构造函数? - How to enforce copy elision, why it won't work with deleted copy constructor? 重载分辨率:是否需要直接转换运算符(由于copy-elision)? - Overload-Resolution: Is a direct conversion operator preferred (as a consequence of copy-elision)? 为什么当用户提供移动构造函数或移动赋值时,复制构造函数和复制赋值会被删除? - Why when user provides move constructor or move assignment, copy constructor and copy assignment will be deleted? 这个副本构造函数是否省略? - Is this copy constructor elision?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM