And*_*owl 18 c++ return language-lawyer compiler-bug move-semantics
#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
}
Run Code Online (Sandbox Code Playgroud)
导致以下错误:
prog.cc: In function 'Base foo()': prog.cc:21:12: error: use of deleted function 'Base::Base(const Base&)'
return d;
^
Run Code Online (Sandbox Code Playgroud)
根据[class.copy]/32:
当满足复制/移动操作的省略标准时,但不满足异常声明,并且要复制的对象由左值指定,或者当返回语句中的表达式是(可能带有括号的)id-时表达式,用于在最内层封闭函数或lambda-expression的body或parameter-declaration-clause中声明的具有自动存储持续时间的对象,首先执行重载决策以选择复制的构造函数,就像对象由rvalue指定一样
如果上面的句子意味着被解析为(copy elision criteria met && lvalue) || (id-expression designating an automatic object),因为这个CWG缺陷似乎表明,为什么这里不适用最后一个条件?Clang和GCC都有编译器错误吗?
另一方面,如果要将句子解析为(copy elision criteria met && (lvalue || id-expression designating an automatic object)),这不是一个非常误导性的措辞值得DR吗?
T.C*_*.C. 11
[class.copy]/32继续:
[...]如果所选构造函数的第一个参数的类型不是对象类型的rvalue引用(可能是cv-qualified),则再次执行重载决策,将对象视为左值.
d作为右值处理的第一个重载决策选择Base::Base(Base&&).类型所选择的构造函数的第一参数的是,然而,不Derived&&但Base&&,这样过载的分辨率的结果被丢弃,并且再次执行重载解析,治疗d作为左值.第二个重载决策选择已删除的复制构造函数.