考虑下面的代码:
class SILPassPipelinePlan final {
public:
SILPassPipelinePlan() = default;
~SILPassPipelinePlan() = default;
SILPassPipelinePlan(const SILPassPipelinePlan &) = default;
SILPassPipelinePlan(SILPassPipelinePlan &&) = delete;
SILPassPipelinePlan x() {
SILPassPipelinePlan P;
return P;
}
};
int main() {
return 0;
}
MSVC报告以下错误:
1.
1.
叮当声和GCC没有。
从规范的角度来看,哪个编译器是正确的?这是MSVC的bug,还是叮当作响的bug?
MSVC来自最新的Visual Studio 2015更新3,Clang是版本3.9。0
C 11在某些场景中引入了隐式移动,包括:
在以下复制初始化上下文中,可以使用移动操作代替复制操作:
>
如果返回语句([stmt.return])中的表达式是一个(可能带括号的)id表达式,该表达式在最内部封闭函数或lambda的正文或参数声明子句中声明了自动存储持续时间-表达,或
[...]
首先执行重载解析以选择副本的构造函数,就像对象由右值指定一样。如果第一次重载解决失败,[...]
Clang(唯一接受的实现,顺便说一句)要么错误地解释了“无法”包含已删除函数的选择,要么过于宽松地应用了[over.match.funcs]/8。见bug 31025。
Wandbox上的所有GCC版本都拒绝此代码。你有没有可能在苹果电脑上测试这个,并使用它的克隆伪装成GCC?
这与P0135无关。Clang只是对当前的[class.copy.elision]/3中的“fails”进行了过于自由的解读,即在这种情况下
首先执行重载解析以选择副本的构造函数,就像对象由右值指定一样。如果第一次过载解析失败或未执行,[...],将再次执行过载解析,将对象视为左值。
超负荷解决方案不会失败;它成功并选择了move构造函数,该构造函数恰好被删除。事情到此为止。
这已被报告为bug 31025。