为什么静态成员函数在重载解析期间被视为具有隐式对象参数?

f87*_*576 16 c++ member-functions language-lawyer overload-resolution

在此链接中: 隐式对象参数

在这句话中:

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

我不明白为什么这里提到静态这个词?隐式对象参数不是指针this(仅存在于非静态函数中)吗?

在此链接中编辑:链接

引用 :

关键字 this 是右值 (C++11 之前) 纯右值 (C++11 起) 表达式,其值是隐式对象参数(调用非静态成员函数的对象)的地址。它可以出现在以下环境中:

Bar*_*rry 5

考虑示例很有用。当你有:

struct C {
    void f(int);
    void f(int) const;
};

C c;
c.f(42);
Run Code Online (Sandbox Code Playgroud)

重载解析如何选择?您实际上可以选择:

//     implicit object  | regular
//         parameter    | parameter
void f(C&,                int        );
void f(C const&,          int        );
Run Code Online (Sandbox Code Playgroud)

随论据(C, int)。最终选择第一个,因为这是一个更好的匹配。


现在,让我们考虑这个例子:

struct D {
    static void g(int);
    void g(long);
};

D d;
d.g(42);
Run Code Online (Sandbox Code Playgroud)

现在,如果我们尝试做同样的事情:

//     implicit object  | regular
//         parameter    | parameter
void g(????????,          int        );
void g(D&,                long        );
Run Code Online (Sandbox Code Playgroud)

我们有两个参数, aD和 an int。我们还不知道是否要调用静态函数,我们仍然需要进行重载解析。这种情况下我们该如何选择呢?非静态成员函数有一个隐式对象参数 ,D&但是对于静态成员函数我们该怎么办呢?

C++ 的答案是我们设计一个假参数,它与所有内容完美匹配:

//     implicit object  | regular
//         parameter    | parameter
void g(contrived-match,   int        );
void g(D&,                long        );
Run Code Online (Sandbox Code Playgroud)

现在,当我们使用 进行重载解析时(D, int),您可以看到静态函数是最佳匹配(第二个参数的转换顺序更好)。

一旦我们选择了静态成员函数,我们就完全忽略对象参数。d.f(42)基本评价为D::f(42). 但直到我们执行重载解析之前,我们并不知道 - 人为参数的存在是为了解决如何实际比较这些情况的问题。

即使只有一个静态成员函数,这仍然适用 - 因为d.f(42)确实有两个参数: thed和 the 42,所以语言需要以d某种方式处理(另一种选择可能是简单地禁止这种语法,D::f(42)如果您想要调用静态成员函数,但这似乎不太好)。