在尝试有选择地继承构造函数(即仅继承其中的一些)时,我找到了一种似乎适用于 GCC 的方法:
#include <string>
#include <iostream>
struct B
{
B()
{
std::cout << std::string("B::B() called") << std::endl;
}
B(int)
{
std::cout << std::string("B::B(int) called") << std::endl;
}
B(long)
{
std::cout << std::string("B::B(long) called") << std::endl;
}
B(long, long)
{
std::cout << std::string("B::B(long, long) called") << std::endl;
}
};
struct D : public B
{
D(int) = delete;
D(long, long)
{
std::cout << std::string("D::D(long, long) called") << std::endl;
}
using B::B;
};
#pragma GCC diagnostic push // Ignore warnings from unused variables
#pragma GCC diagnostic ignored "-Wunused-variable"
int main()
{
B b0;
B b1(1);
B b2(1, 2);
D d0;
// D d1(1); error despite we might wish B::B(long) to be selected
D d2(1, 2);
}
#pragma GCC diagnostic pop
即那些我不想要的
using
?我只是在派生类中声明或定义我自己的构造函数,两者似乎都消除了继承的重载。这个标准符合吗?我还注意到, delete
声明是第一个还是最后一个似乎并不重要。这也太符合标准了吧?它与选择性继承并不完全相同,因为在解决重载时删除的重载仍然会引起注意(如注释行所示)。
如果您希望 D 的 int 构造函数调用 B 的 long 构造函数,您可以转发该调用。
using
这就像你写的一样
D(int x) : B((long)x) {}
但这引出了一个问题:我们为什么要这样做,如果类型应该总是隐式转换,那么为什么首先要实现所有这些实现。