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 显示基类的复制/移动构造函数不是继承的。有人可以提供标准中的解释吗?谢谢。
新的措辞位于[over.match.funcs]/8中:
\n\n\n\n\n从类类型
\n\nC([class.inhctor.init]) 继承的构造函数,其第一个参数类型为 \xe2\x80\x9c,引用cv1P\xe2\x80\x9d(包括从模板实例化的此类构造函数),该构造函数被排除在外。如果参数列表只有一个参数并且与引用相关并且与引用相关,则构造cv2 类型的对象时的一组候选函数。[例子:DCPPDRun Code Online (Sandbox Code Playgroud)\n\nstruct 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\xe2\x80\x94结束示例]
\n
在您的示例中,B\ 继承的复制构造函数被排除在候选集合之外(该构造函数具有引用类型的第一个参数const B,参数列表只有一个参数 - b,并且B和D与引用相关)。