隐藏重载的虚函数

15

考虑以下结构体的层级:

struct I1 {
    virtual void doit() = 0;
};

struct I2 {
    virtual void doit(int) = 0;
};

struct I12 : I1, I2 {
    using I1::doit;
    using I2::doit;
};

struct Derived : I12 {
    void doit(int) override {}
};

使用clang编译这个程序(或者使用带有-Woverloaded-virtual选项的g++编译器)会给我一个警告:

编译结果为:

使用clang编译这个程序(或者使用带有-Woverloaded-virtual选项的g++编译器)会给我一个警告:

'Derived::doit' hides overloaded virtual function [-Woverloaded-virtual]

然而,如果我将I12更改为以下内容,在clang下它可以编译通过,但是g++ -Woverloaded-virtual仍然会发出警告:

struct I12 : I1, I2 {
    using I1::doit;
    void doit(int) override = 0;
};

使用I2::doitvoid doit(int) override = 0之间有什么区别?幼稚的想法是,我原本认为前者足以告诉编译器我知道有两个版本的doit


你使用的编译器是什么?我在gcc或MSVS中无法得到警告,但在clang中可以。 - NathanOliver
是的,你正在隐藏它。那么你的问题是什么?如何消除冗长的警告? - songyuanyao
@NathanOliver 我使用了clang,但是使用g++并开启警告会显示不同的行为。 - phimuemue
2
C++标准并不要求编译器对任何特定情况发出警告。编译器可以自由选择警告这个、那个或其他什么。一个编译器可能会在特定情况下发出警告,而第二个编译器则会在没有警告的情况下进行处理。这并不意味着任何一个编译器是对的或错误的。 - Sam Varshavchik
@SamVarshavchik 标准规定编译器在许多情况下应发出诊断。警告还是错误取决于编译器。我只是不知道这种情况是否被规定,或者它只是编译器作为额外奖励而执行的操作。 - NathanOliver
显示剩余5条评论
1个回答

5

它抱怨doitDerived中被隐藏。修复方法:

struct Derived : I12 {
    using I12::doit; // Bring all doit declarations from I12 into this scope.
    void doit(int) override {}
};

谢谢您的建议,但在我的具体情况下,我有Derived1Derived2,...,甚至可能有doit1doit2...,所以我不想在每个地方都重复所有这些using声明,而是希望只在一个中心位置进行。 - phimuemue
@phimuemue,采用这种设计可能更容易关闭警告。-Wno-overloaded-virtual。否则,您将不得不在各个地方添加“using”,因为这就是C++中名称隐藏的工作方式。 - Maxim Egorushkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接