我设计了以下代码片段来显示我的问题(原始问题更复杂):
#include <string>
struct A
{
A(int, int) {}
A(int p1 = 0, std::string p2 = "", int p3 = 0) {} // string for breaking ambiguity with previous ctor
// There are a lot more of constructors for A class
};
struct B : public A
{
using A::A; // I want to inherit many base constructors in order to save work
// But I need this particular constructor and it should override the
// equivalent base constructor
B(int p1 = 0, std::string p2 = "", int p3 = 0) {}
};
int main(int argc, char *argv[])
{
B b(1); // gives "error: call to constructor of 'B' is ambiguous", what
// of course is true, but I would want to inherit the other
// base constructors. If I comment using A::A ==> this line compiles
B b2(2, 3); // But if I comment using A::A ==> this line does not compile
}
所以,我的问题是:有没有办法打破这种歧义而不隐藏其他许多具有基类的构造函数?
提前致谢
答案 0 :(得分:6)
当前继承的构造函数规范是......有些搞砸了。继承A(int p1 = 0, std::string p2 = "", int p3 = 0)
构造函数隐式声明了三个签名:B(int)
,B(int, std::string)
,B(int, std::string, int)
,由于B
的构造函数声明,其中只有最后一个被禁止。
N4429,一个修复当前规范的许多问题的提案,在上次委员会会议上通过了设计审查,如果通过,将解决您的问题。
解决方法是在B
中编写一组委托构造函数,而不是使用默认参数:
B() : B(0) {}
B(int p1) : B(p1, "") {}
B(int p1, std::string p2) : B(p1, std::move(p2), 0) {}
B(int p1, std::string p2, int p3) {}
这会抑制从继承该基类构造函数声明的所有三个签名。
答案 1 :(得分:2)
如果定义派生类构造函数,则应在初始化列表中调用基类构造函数,如下所示:
struct B : public A
{
// using A::A; // I want to inherit many base constructors in order to save work
// But I need this particular constructor and it should override the
// equivalent base constructor
B(int p1 = 0, int p2 = 0, int p3 = 0):A(p1,p2,p3) {}
};
请注意,您不需要使用using语句来解决派生类中的歧义using A::A;
。当您公开派生时,您将获得基类的所有公共和受保护组件在派生类中可用。