简体   繁体   中英

confusion overloading memberfunctions on rvalues and lvalues

I have the following setup:

struct foo
{
    void bar( ) &  { std::cout << "lvalue\n"; }
    void bar( ) && { std::cout << "rvalue\n"; }

    ~foo( ) { bar( ); }
};


int main( int arg, char **argv )
{
    foo{ }.bar();
}

which leads to the output of

rvalue
lvalue

I do not understand the output of the dtor which is always lvalue no matter how hard I try. While I agree that taking the address similar to

(*this).bar( ); // sure enough this will print lvalue

calls the lvalue-overload I do not understand why I can never get an output of rvalue for the dtor.

I find this strange since the object is an rvalue first and somehow binds to an lvalue before being destructed. What's the matter here?

this is a prvalue, but *this is a lvalue, naturally it will call lvalue ref-qualifiers:

§ 5.3.1 Unary operators [expr.unary.op]

The unary * operator performs indirection : the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

From cppreference, this pointer :

When a non-static class member is used in any of the contexts where the this keyword is allowed (non-static member function bodies, member initializer lists, default member initializers), the implicit this-> is automatically added before the name , resulting in a member access expression (which, if the member is a virtual member function, results in a virtual function call).

Note : calling this-> is equivalent to calling (*this).

#include <iostream>

struct foo
{
    void bar( ) &  { std::cout << "lvalue\n"; x(); }
    void bar( ) && { std::cout << "rvalue\n"; x(); }

    void x( ) & { std::cout << "x lvalue\n"; }
    void x( ) && { std::cout << "x rvalue\n"; }

    ~foo( ) { bar( ); }
};


int main( int arg, char **argv )
{
    foo{ }.bar();
}

Prints:

rvalue
x lvalue
lvalue
x lvalue

If, for some reason, you really want to call a rvalue function, you could cast the this pointer to a rvalue reference:

~foo( ) { static_cast<foo&&>(*this).bar( ); }

Or using std::move :

~foo( ) { std::move(*this).bar( ); }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM