为什么私有继承不能解决静态函数的歧义?(在 MSVC 中测试)



我想知道为什么对静态函数的调用是模棱两可的,即使两者中的一个显然不可能调用,因为它是私有的。我希望我可以使用私有/受保护的继承来帮助编译器解决歧义。

它是特定于 MSVC 还是在标准中以某种方式指定?

struct A
{
    static int num() { return 0; }
};
struct B
{
    static int num() { return 1; }
};
struct C : public A, private B
{};
int main()
{
     C::num(); // Ambiguous access of num
}

背景是,我正在尝试一种通过继承在许多派生类(C,D,E,F,G)中重用重载行为(A中的重载行为)的方法,以以某种方式遵守"不要重复自己"的规则。

是的,

它在C++标准§3.4节[basic.lookup]中指定

访问规则(条款 11)仅在名称查找和函数重载解析(如果适用)成功后才会考虑

名称查找并不关心可访问性:它同时查找A::numB::num,因此编译器存在歧义。

您可以使用以下命令显式调用A::num

C::A::num();

如果你显式尝试调用B::num,那么你的编译器确实会发出一个访问错误:

C::B::num(); // Error

您还可以显式地将基名称引入派生类中的范围内,这将修复歧义:

struct C : public A, private B
{
    using A::num;    
};

为了帮助编译器,你可以这样做

 struct C : public A, private B
 {
      using A::num;
 };

有意考虑解决重载的私有成员。

假设你有

class C {
public:
  static void f(int);
  static void g();
private:
  static void f(long);
};
void C::g() {
  f(0L); // okay
}
void g() {
  f(0L); // error, does not silently call f(int)
}
在重载

解析期间仅使公共成员可用会导致对代码的非常令人惊讶的重新解释,其中看起来应该以完全相同的方式工作的代码会静默地调用不同的重载。

使此类代码成为错误被认为比替代方案更麻烦。

最新更新