提问者:小点点

已删除的构造函数-MSVC报告错误,Clang没有


考虑下面的代码:

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


共2个答案

匿名用户

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。