删除复制构造函数时,为什么重载决议不会返回到参考基类的构造函数?

Mik*_*yke 4 c++ language-lawyer

作为这个问题的后续问题

class Base {
    public:
    virtual ~Base() {}
    virtual void func() = 0;
};

class A : public Base {
    public:
     void func() override { std::cout << this << std::endl; }
};

class B : public Base {
    private:
     Base& base;

     public:
      B(B&) = delete;
      B(Base& b) : base(b) {}
      void func() override { std::cout << &base << std::endl; }
};

int main()
{
  A a;
  B b(a);
  B c(b);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

B(Base& b)删除复制构造函数时,为什么重载决议不会回退到引用基类 ( ) 的构造函数?

Art*_*yer 6

因为= delete是一个仍然是构造函数的定义(它被定义为删除)。被删除的函数在重载决议中仍然是可能的候选者,在这种情况下,复制构造函数仍然是最可行的候选者,它被选中。由于引用了已删除的函数,因此程序格式错误。

从标准,[dcl.fct.def.delete]:

  1. 删除定义的函数是一个函数定义,其功能体的形式为= delete ;[...]甲删除功能是与已删除的定义或为已删除,其隐含地定义的功能的功能。
  2. 隐式或显式引用已删除函数而不是声明它的程序是格式错误的。

并且很容易理解为什么 for 的定义B::B(B&)B::B(Base&)类型的左值更可行B

  • 通俗地说,`=delete` 并不意味着“不存在”,而是“我存在,但只是作为检测错误的接收器” (3认同)