隐藏私有的重载虚拟功能?

Sac*_*han 9 c++ inheritance g++ clang++

我有一个类层次结构,其工作方式大致如下:

class A 
{ 
protected: 
    virtual void f(int) = 0;
};

class B 
{ 
protected: 
    virtual void f(char*) = 0;
};

class DA : A 
{ 
private:
    virtual void f(int) override {}
};

class DB : public DA, B 
{ 
private:
    virtual void f(char*) override {}
};
Run Code Online (Sandbox Code Playgroud)

当我尝试使用clang(或gcc,就此问题)编译时,它会给我警告

<source>:22:18: warning: 'DB::f' hides overloaded virtual function [-Woverloaded-virtual]
    virtual void f(char*) override {}
                 ^
<source>:16:18: note: hidden overloaded virtual function 'DA::f' declared here: type mismatch at 1st parameter ('int' vs 'char *')
    virtual void f(int) override {}
                 ^
Run Code Online (Sandbox Code Playgroud)

我明白了,但它真的应该发出警告吗?毕竟,DB甚至看不到隐藏的功能(甚至可能通过巧合命名相同).

如果它不是私人的,我可以使用

using DA::f;
Run Code Online (Sandbox Code Playgroud)

当然要澄清,但功能是私密的,DB甚至不知道它,当然不应该暴露它.

有没有办法解决这个问题而不会停用该警告,即告诉编译器所有内容都是按照预期设计的?

Arn*_*gel 3

毕竟,DB 甚至看不到隐藏函数(甚至可能巧合地命名为相同)。

可访问性和可见性在 C++ 中是不同的概念。DA::f()默认情况下在 内部可见DB(然后被 隐藏DB::f()),但它不可访问,因为它在 内部是私有的DA,并且DB不是 的友元DA。有人可能会说,隐藏不可访问的函数是无害的,因为无论如何都无法调用它。但是,隐藏函数和不可访问函数之间的区别可能很重要,因为可见函数和不可访问函数确实参与重载决策。如果db是 类型的对象DB,那么它会db.f(0)做什么?如果DA::f()可见但不可访问,则它将被选为最佳匹配,并且编译器将发出诊断信息,因为它不可访问,因此无法调用。但是,如果DA::f()隐藏,编译器将选择接受指针的重载,并将文字视为0空指针。