6

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

它是特定于 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中的行为),以某种方式遵守不重复的规则你自己。

4

3 回答 3

7

是的,它在 C++ 标准第 3.4 节 [basic.lookup] 中指定

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

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

您可以显式调用A::num

C::A::num();

如果您明确尝试调用B::num,那么您的编译器确实会发出访问错误:

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

您还可以显式地将基名称纳入派生类的范围内,这将解决歧义:

struct C : public A, private B
{
    using A::num;    
};
于 2014-12-28T19:03:42.677 回答
3

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

 struct C : public A, private B
 {
      using A::num;
 };
于 2014-12-28T19:05:03.193 回答
2

私有成员被有意考虑用于重载解决方案。

假设你有

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)
}

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

使这样的代码成为错误被认为比替代方法更容易。

于 2014-12-28T19:04:26.153 回答