copy/move构造函数可以通过c++17中的using-declaration继承吗?

Can copy/move constructors be inherited by using-declaration in 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.

中从继承的构造函数中显式排除 copy/move 构造函数

For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.

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

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

A constructor inherited from class type C ([class.inhctor.init]) that has a first parameter of type “reference to cv1 P” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2 D if the argument list has exactly one argument and C is reference-related to P and P is reference-related to D. [ Example:

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

end example ]

在您的示例中,B 的继承复制构造函数被排除在候选集合之外(该构造函数的第一个参数类型为 const B,参数列表只有一个参数- bBD 是参考相关的)。

你引用的段落实际上并没有阻止 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

A constructor inherited from class type C (class.inhctor.init) that has a first parameter of type “reference to cv1 P” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2 D if the argument list has exactly one argument and C is reference-related to P and P is reference-related to D.