Why are static member functions considered to have an implicit object parameter during overload resolution?
Asked Answered
A

3

17

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:

Assoil answered 3/6, 2022 at 7:50 Comment(9)
It doesn't say that static functions receive a this pointer. But, in all C++ standards since 1998, the standard requires that both static and non-static member functions receive an implicit object parameter for purposes of overload resolution. Among other things, that's why - if some_object is an instance of X - the syntax some_object.function() can be used to call X::function() even if function() is a static member function of X.Deplume
So Implicit object parameter is Existed in static function but not for using as the ( this ) pointer but only for making us able to call it ( static function ) form the object ( instance ) not only form the class directly . and the Implicit object parameter does not have any other usage with static function , right ? @DeplumeAssoil
As far as I understand, yes. It's about making things consistent (in terms of picking which overloaded function to call from a bunch of candidates) for static and non-static member functions.Deplume
You said " It's about making things consistent (in terms of picking which overloaded function to call from a bunch of candidates) for static and non-static member functions" do the answer which was written by MR.Alex ( in this question ) explain this part ( consistent (in terms of picking which overloaded function to call from a bunch of candidates) for static and non-static member functions ) of your comment totally correctly ? @DeplumeAssoil
Call it a phantom parameter. It's there in theory but not in practice.Mongrel
I mean You said " It's about making things consistent (in terms of picking which overloaded function to call from a bunch of candidates) for static and non-static member functions" is the answer which was written by Alex Sveshnikov ( in this question ) an example of what you exactly mean by this quote ? and if your answer is no . please explain this quote because I do not understand this quote @DeplumeAssoil
please answer my comment which is exactly above this comment @DeplumeAssoil
isn't your first comment exactly what Alex Sveshnikov said in his answer ? and you said " but discussion seems specific to C++23. Whereas the same requirement for treating static member functions as if they have an implicit object parameter has existed in all C++ standards" so I do not understand where is the quote that is seems specific to C++23 ? and i am sorry for bothering you @DeplumeAssoil
please answer my comment which is exactly above this comment . and i am sorry for bothering you @DeplumeAssoil
I
9

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

Iodism answered 7/6, 2022 at 16:22 Comment(3)
So Implicit object parameter is Existed in static function but not for using as the(this)pointer but only for making us able to call it(static function)form the object(instance)not only form the class directly. and the Implicit object parameter doesn't have any other usage with static function (Because if a static function doesn't have an Implicit object parameter then a static function can overload a non-static function with the same explicit parameters then if you try to call any of them(the static function or the non-static function)form the object(instance)you will get an error),right?Assoil
@Assoil The answer to your questions is... in the answer. Also, you do not have to add thirteen question marks to ask a question. One is sufficient.Iodism
Okay . sorry for bothering you but english is not my native language . so when you said " the contrived parameter exists to solve the problem of how to actually compare these cases " . does this sentence mean exactly that the Implicit object parameter is Existed in static functions only for making us able to call it ( static functions ) from an object ( an instance ) not only from the class directly ( in other words the Implicit object parameter doesn't have any other usage with static functions ) ? @IodismAssoil
L
2

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.

Lo answered 3/6, 2022 at 8:9 Comment(4)
So Implicit object parameter is Existed in static function but not for using as the(this)pointer but only for making us able to call it(static function)form the object(instance)not only form the class directly.and the Implicit object parameter doesn't have any other usage with static function(Because if a static function doesn't have an Implicit object parameter then a static function can overload a non-static function with the same explicit parameters then if you try to call any of them(the static function or the non-static function)form the object(instance)you will get an error),right? @alexAssoil
@Assoil yes, and as mentioned by Anoop Rana, the implicit object parameter is not this, it's an object which this is pointing to.Lo
When you said that : " and as mentioned by Anoop Rana, the implicit object parameter is not this, it's an object which this is pointing to " every time you said ( in the quote which is above ) " this " you exactly meant " the ( this ) pointer " , right ? @Alex SveshnikovAssoil
@Assoil yes, this pointerLo
S
2

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)

Selfappointed answered 3/6, 2022 at 8:42 Comment(1)
Comments are not for extended discussion; this conversation has been moved to chat.Punjab

© 2022 - 2024 — McMap. All rights reserved.