【问题标题】:Can copy/move constructors be inherited by using-declaration in c++17?复制/移动构造函数可以通过 c++17 中的 using-declaration 继承吗?
【发布时间】:2020-05-05 14:23:19
【问题描述】:
struct B {
  B(int) {}
  B(B const&) {}
};

struct D: B {
  using B::B;
};

int main(void) {
  B b(5);
  D d(b); // error
  return 0;
}

c++14 在 12.9 [class.inhctor]/p3 中从继承的构造函数中明确排除了复制/移动构造函数。

对于继承的候选集中的每个非模板构造函数 除了没有参数的构造函数之外的构造函数或 具有单个参数的复制/移动构造函数,构造函数是 隐式声明具有相同的构造函数特征,除非 有一个用户声明的具有相同签名的构造函数 出现 using 声明或构造函数的完整类 将是该类的默认、复制或移动构造函数。

但是我在 c++17 中找不到任何详细的描述。 clang/gcc 表明基类的复制/移动构造函数不是继承的。有人可以提供标准中解释的地方吗?谢谢。

【问题讨论】:

    标签: c++ c++14 c++17 language-lawyer inherited-constructors


    【解决方案1】:

    新的措辞在[over.match.funcs]/8:

    从类类型 C ([class.inhctor.init]) 继承的构造函数,其第一个参数类型为“引用 cv1 P”(包括从如果参数列表只有一个参数并且CP 和@ 引用相关,则在构造cv2 D 类型的对象时,从候选函数集中排除987654327@ 与 D 引用相关。 [例子

    struct A {
      A();                                  // #1
      A(A &&);                              // #2
      template<typename T> A(T &&);         // #3
    };
    
    struct B : A {
      using A::A;
      B(const B &);                         // #4
      B(B &&) = default;                    // #5, implicitly deleted
    
      struct X { X(X &&) = delete; } x;
    };
    
    extern B b1;
    B b2 = static_cast<B&&>(b1);            // calls #4: #1 is not viable, #2, #3, and #5 are not candidates
    struct C { operator B&&(); };
    B b3 = C();                             // calls #4
    

    结束示例 ]

    在您的示例中,B 的继承复制构造函数被排除在候选集合之外(该构造函数的第一个参数类型引用 const B,参数列表只有一个参数 - b,并且BD 与引用相关)。

    【讨论】:

      【解决方案2】:

      您引用的段落实际上并没有阻止 C++14 中复制构造函数的继承。请考虑一下:

      B(B const&, int = 42) {}
      

      这是一个复制构造函数,但它有两个参数。该段落仅排除了具有单个参数的复制构造函数。当你提供这两个参数时,你实际上可以用这个构造函数初始化一个D 对象。

      g++ 错误消息提供了一些见解。

      note:   an inherited constructor is not a candidate for initialization from an expression of the same or derived type
      

      啊哈!在标准草案中快速搜索发现this

      从类类型 C (class.inhctor.init) 继承的构造函数具有“对 cv1 P 的引用”类型的第一个参数(包括从模板实例化的此类构造函数)从集合中排除在构造 cv2 D 类型的对象时,如果参数列表只有一个参数并且 CP 和 P 与 D 引用相关。

      【讨论】:

      • D d(X{});仍然无法编译。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 2019-01-12
      • 2011-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多