可以通过 c++17 中的 using 声明继承复制/移动构造函数吗?

Han*_*Han 6 c++ language-lawyer inherited-constructors c++14 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Bar*_*rry 5

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

\n\n
\n

从类类型C([class.inhctor.init]) 继承的构造函数,其第一个参数类型为 \xe2\x80\x9c,引用cv1 P \xe2\x80\x9d(包括从模板实例化的此类构造函数),该构造函数被排除在外。如果参数列表只有一个参数并且与引用相关并且与引用相关,则构造cv2 类型的对象时的一组候选函数。[例子DCPPD

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

\xe2\x80\x94结束示例]

\n
\n\n

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

\n