【问题标题】:Why does overload resolution not fall back to constructor with reference to base class when copy-constructor is deleted?为什么在删除复制构造函数时,重载解析不会退回到引用基类的构造函数?
【发布时间】:2021-08-03 10:07:24
【问题描述】:

作为this question 的后续问题:

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;
}

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

【问题讨论】:

    标签: c++ language-lawyer


    【解决方案1】:

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

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

    1. 函数的已删除定义是一个函数定义,其function-body的形式为= delete ; [...]已删除函数 是具有已删除定义的函数或隐式定义为已删除的函数。
    2. 隐式或显式引用已删除函数而不是声明它的程序是格式错误的。

    很容易看出为什么B::B(B&amp;) 的定义比B::B(Base&amp;) 更适合B 类型的左值

    【讨论】:

    • 通俗地说,=delete 并不是“不存在”,而是“我存在,但只是作为检测错误的接收器”
    猜你喜欢
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2018-02-24
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    相关资源
    最近更新 更多