【问题标题】:Why does function overload resolution in C++ consider non-static member functions for static calls?为什么 C++ 中的函数重载解析会考虑静态调用的非静态成员函数?
【发布时间】:2019-03-24 15:51:05
【问题描述】:

我想知道为什么 C++ 中的函数重载解析在调用静态方法时会考虑非静态成员函数。

我已阅读文档here 并指出

如果任何候选函数是成员函数(静态或非静态),但不是构造函数,则将其视为具有额外参数(隐式对象参数),该参数表示调用它们并出现的对象在第一个实际参数之前。

所以考虑下面的代码。

struct A {
   static void foo(int a, float b){...}
   void foo(float a, int b){...}
};

那么A::foo(1.f, 1.f)的调用就模棱两可了。

静态成员函数被考虑用于非静态函数调用的重载解析,这是有道理的。

A a;
a.foo(1, 1.f); //can safely call static method

但是为什么它也以相反的方式进行(在使用Class::function 调用函数时考虑非静态成员函数)?为什么编译器不能直接选择static void foo(int a, float b)

【问题讨论】:

  • 我 90% 确定 A 格式不正确。
  • 你是什么意思?没有模棱两可的调用,它应该可以正常编译。
  • 嗯...你是对的。我误以为您的示例具有完全相同的参数类型(对我来说这是一天的结束)。抱歉,A 的格式并不错误。
  • 您可以使用class:: 语法调用非静态成员。编译器无法仅从该语法中知道您是在调用静态函数还是非静态函数。
  • 你是对的!我不明白为什么我得到这么多反对票。对于有经验的 C++ 开发人员来说,这可能是一个愚蠢的问题,但如果您不考虑继承,这并不是很明显。

标签: c++


【解决方案1】:

为什么编译器不能直接选择static void foo(int a, float b)

我对您的问题的理解是,由于非实例 A:: 前缀,您假设语法 A::foo 是明确的。但是看看这个场景:

struct A {
   static void foo(int, float);
   void foo(float, int);
};

struct B : A {
   // Hide the base class foo
   void foo()
   {
      // Now explicitly call it... this is ambiguous!
      A::foo(1.f, 1.f);
   }
};

因此,A:: 前缀可以引用static 和非static 成员函数,具体取决于上下文。编译器不能假定它仅引用 static 成员函数。

在更多情况下,需要像 A::foo 这样的合格非static 成员函数调用,例如在菱形继承结构中(如果你不使用virtual 继承)。这就是为什么可以像这样调用任何成员函数(即使它是不必要且没有意义的:A a; a.A::foo(1, 2.f);

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2022-01-22
    • 2011-05-31
    相关资源
    最近更新 更多