为什么在过载分辨率期间认为静态成员函数具有隐式对象参数?

发布于 2025-02-04 01:21:52 字数 723 浏览 6 评论 0原文

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

在这句话中:

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

我不明白为什么这里提到 static 一词?隐式对象参数不是this指针(仅在 non static 函数中存在)吗?

编辑 在此链接中: link

QUOTE QUOTE:

关键字这是一个rvalue(直到C ++ 11)prvalue(自C ++ 11)的表达式,其值是隐式对象参数的地址(呼叫非静态成员函数的对象)。它可以出现在以下上下文中:

In this link : Implicit object parameter

In this quote :

If any candidate function is a member function (static or non-static) that does not have an explicit object parameter (since C++23), but not a constructor, it is treated as if it has an extra parameter (implicit object parameter) which represents the object for which they are called and appears before the first of the actual parameters.

I do not understand why the word static is mentioned here? Isn't the implicit object parameter the this pointer ( which only exists in non-static functions ) ?

Edit
in this link : link

quote :

The keyword this is a rvalue (until C++11)prvalue (since C++11) expression whose value is the address of the implicit object parameter (object on which the non-static member function is being called). It can appear in the following contexts:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

短暂陪伴 2025-02-11 01:21:52

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

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

C c;
c.f(42);

超载分辨率选择如何?您有效地选择了:

//     implicit object  | regular
//         parameter    | parameter
void f(C&,                int        );
void f(C const&,          int        );

使用参数(c,int)。最终选择了第一个,因为它是更好的匹配。


现在,让我们考虑一下这个示例:

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

D d;
d.g(42);

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

//     implicit object  | regular
//         parameter    | parameter
void g(????????,          int        );
void g(D&,                long        );

我们有两个参数,一个dint。我们不知道我们是否要调用静态功能,我们仍然必须进行超负荷分辨率。在这种情况下,我们如何选择?非静态成员函数具有隐式对象参数,d&,但是我们对静态一个有什么作用?

C ++答案是我们构成一个假参数,这是一切的完美匹配:

//     implicit object  | regular
//         parameter    | parameter
void g(contrived-match,   int        );
void g(D&,                long        );

现在,当我们使用(D,INT)进行超载分辨率时,您可以看到静态函数是最好的匹配(第二个参数的更好的转换序列)。

一旦选择静态成员函数,我们就会完全忽略对象参数。 df(42)基本上评估为d :: f(42)。但是,直到我们执行过载分辨率之前,我们才知道这一点 - 存在的参数是为了解决如何实际比较这些情况的问题。

即使只有一个静态成员函数,这仍然适用 - 因为df(42)确实有两个参数:d42 ,因此该语言需要以某种方式处理d(可以简单地禁止此语法,需要d :: f(42)如果您想致电静态成员功能,但这似乎不太好)。

It's useful to consider examples. When you have:

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

C c;
c.f(42);

How does overload resolution pick? You effectively have a choice of:

//     implicit object  | regular
//         parameter    | parameter
void f(C&,                int        );
void f(C const&,          int        );

With the arguments (C, int). That ends up picking the first one, for being a better match.


Now, let's think of this example:

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

D d;
d.g(42);

Now, if we try to do the same thing:

//     implicit object  | regular
//         parameter    | parameter
void g(????????,          int        );
void g(D&,                long        );

We have two arguments, a D and an int. We don't know if we're going to call a static function or not yet, we still have to do overload resolution. How do we pick in this case? The non-static member function has an implicit object parameter, D&, but what do we do for the static one?

The C++ answer is we contrive a fake parameter, that is a perfect match for everything:

//     implicit object  | regular
//         parameter    | parameter
void g(contrived-match,   int        );
void g(D&,                long        );

And now, when we do overload resolution with (D, int), you can see that the static function is the best match (better conversion sequence for the second parameter).

Once we pick the static member function, we then ignore the object argument entirely. d.f(42) basically evaluates as D::f(42). But we didn't know that until we performed overload resolution - the contrived parameter exists to solve the problem of how to actually compare these cases.

This still applies even if there were just the one static member function - since d.f(42) does have two parameters: the d and the 42, so the language needs to handle the d somehow (the alternative could've been to simply disallow this syntax, requiring D::f(42) if you wanted to call a static member function, but that seems a lot less nice).

缱绻入梦 2025-02-11 01:21:52

考虑如果您没有此规则,并且具有具有相同(明确)参数的静态方法和非静态方法,会发生什么。然后,将非静态方法添加其他隐式参数(this),而不是静态方法。这将使这两种方法的参数列表不同,并允许使用具有相同显式参数的非静态方法将静态方法重载。

Consider what happens if you don't have this rule and have a static method and non-static method with the same (explicit) parameters. Then to the non-static method an additional implicit parameter (this) will be added, but not to the static method. This will make the list of parameters of both methods different and will allow to overload the static method with non-static method with the same explicit parameters.

转身泪倾城 2025-02-11 01:21:52

首先,首先,隐式对象参数 指针之间存在差异。前者是参考类型,而后者是关键字,并且是指针类型的rvalue。例如,对于const合格的非静态成员函数,隐式对象参数是类型const x&的 pointer属于类型代码> const x*。对于非const非静态成员函数,隐式对象参数是类型x&的类型是类型x*。这可以被确认在这里


不是隐式对象参数(此)指针(((此)指针)仅适用于非静态函数)

否,静态和非静态成员函数都具有隐式对象参数上可以看出。 Match.funcs#2 哪个指出:

一组候选功能可以包含成员和非成员功能,以在同一参数列表中解决。因此,该参数和参数列表在此异质集中是可比性的,成员函数被认为具有额外的参数,称为隐式对象参数,该参数代表称为成员函数的对象。 为了解决过载的目的,static和非静态成员函数都具有隐式对象参数,但构造函数却没有。

(强调我)

First things first, there is a difference between implicit object parameter and this pointer. The former is a reference type while the latter is a keyword and is an rvalue of pointer type. For example for a const qualified non-static member function the implicit object parameter is of type const X& while the this pointer is of type const X*. While for a non-const nonstatic member function the implicit object parameter is of type X& and the this is of type X*. This can be confirmed here.


isn't Implicit object parameter the ( this ) pointer ( which ( the ( this ) pointer ) only works with non-static functions )

No, both static as well as non static member functions have an implicit object parameter for the purposes of overload resolution as can be seen from over.match.funcs#2 which states:

The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list. So that argument and parameter lists are comparable within this heterogeneous set, a member function is considered to have an extra parameter, called the implicit object parameter, which represents the object for which the member function has been called. For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.

(emphasis mine)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文