4
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 中的继承构造函数中明确排除了复制/移动构造函数。

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

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

4

2 回答 2

4

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

从类类型C([class.inhctor.init]) 继承的具有类型“对cv1 P的引用”的第一个参数的构造函数(包括从模板实例化的这种构造函数)在构造对象时从候选函数集中排除如果参数列表只有一个参数并且与引用相关并且与引用相关,则键入cv2 。[示例DCPPD

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引用相关)。

于 2020-05-05T15:18:42.017 回答
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

啊哈!在标准草案中快速搜索发现这一点

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

于 2020-05-05T15:30:21.367 回答