Vinod
Vinod

Reputation: 1043

implicit object parameter and this pointer

With reference to Non-static member functions, under

const-, volatile-, and ref-qualified member functions

it is mentioned:

A non-static member function can be declared with no ref-qualifier, with an lvalue ref-qualifier (the token & after the parameter list) or the rvalue ref-qualifier (the token && after the parameter list). During overload resolution, non-static cv-qualified member function of class X is treated as follows:

no ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X and is additionally allowed to bind rvalue implied object argument

lvalue ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X

rvalue ref-qualifier: the implicit object parameter has type rvalue reference to cv-qualified X

Note: unlike cv-qualification, ref-qualification does not change the properties of the this pointer: within a rvalue ref-qualified function, *this remains an lvalue expression.

In this context, what is the difference between the implicit object parameter and *this?

Upvotes: 3

Views: 986

Answers (2)

Darklighter
Darklighter

Reputation: 2192

ref-qualifiers allow function overloading based on the type of reference of an expression.

Since there are no pointers (or references) to references in C++ this can’t point to a (n rvalue) reference, so *this can’t be an rvalue.

rvalue, lvalue and reference (intentionally) loose their relevance once the function is invoked.

Upvotes: 2

user7860670
user7860670

Reputation: 37513

I think the difference can be illustrated with the following example:

When overload resolution selection relies on CV-qualifier *this will have an appropriate CV qualifier just like an implicit object parameter:

struct t_Tester
{
    constexpr auto Probe(/* t_Tester & param */) { return 1; }
    constexpr auto Probe(/* t_Tester const & param */) const { return 2; }
    constexpr auto Test(/* t_Tester const & param */) const { return (*this).Probe(); }
};

static_assert(2 == t_Tester{}.Test());

However when overload resolution selection relies on rvalue / lvalue reference qualifier *this will be still an lvalue even if implicit object parameter is an rvalue reference and the object itself is an rvalue:

struct t_Tester
{
    constexpr auto Probe(/* t_Tester & param */) & { return 1; }
    constexpr auto Probe(/* t_Tester && param */) && { return 2; }
    constexpr auto Test(/* t_Tester && param */) && { return (*this).Probe(); }
};

static_assert(1 == t_Tester{}.Test());

Note: Invoking function in class scope without using this pointer explicitly (like return Probe();) will use implied object argument (which is the same as (*this)) that should not be confused with implicit object parameter (which is just an invisible part of member function signatures used during overload resolution).

Upvotes: 2

Related Questions