#include <memory>
struct Base
{
Base() = default;
Base(Base const&) = delete;
Base(Base&&) = default;
};
struct Derived : Base
{
Derived() = default;
Derived(Derived const&) = delete;
Derived(Derived&&) = default;
};
auto foo()
-> Base
{
Derived d;
return d; // ERROR HERE
}
导致以下错误:
prog.cc: In function 'Base foo()': prog.cc:21:12: error: use of deleted function 'Base::Base(const Base&)'
return d;
^
根据[class.copy]/32:
When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the object to be copied is designated by an lvalue, or when the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue
如果上面的句子被解析为 (复制省略条件满足 && lvalue) || (id-expression 指定一个自动对象)
,如 this CWG defect似乎表明,为什么最后一个条件在这里不适用? Clang 和 GCC 中是否存在编译器错误?
另一方面,如果句子被解析为(复制省略条件满足&&(左值|| id-expression指定一个自动对象))
,这不是很误导性的措辞值得 DR?
最佳答案
[class.copy]/32 继续:
[...] 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.
第一个重载决议,将 d
视为右值,选择 Base::Base(Base&&)
。然而,所选构造函数的第一个参数的类型不是 Derived&&
而是 Base&&
,因此该重载解析的结果被丢弃,您再次执行重载解析,将d
作为左值。第二个重载决议选择已删除的复制构造函数。
关于c++ - 为什么在返回从函数的返回类型派生的类型的本地对象时不选择 move 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40039379/