在c++17中可以通过使用-声明来继承复制/移动构造函数吗?

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显示基类的复制/移动构造函数不是继承的。有没有人能提供一下标准中的解释?谢谢。


解决方案

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

构造CV2类型的对象时,如果参数列表正好有一个参数且C是引用,则从类类型C([class.inhctor.init])继承而来的构造函数(包括从模板实例化的构造函数)的第一个参数类型为"Reference to CV1P"的构造函数将被排除在候选函数集中。[示例:

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

相关文章