混淆在右值和左值上重载成员函数

confusion overloading memberfunctions on rvalues and lvalues

我有以下设置:

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

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


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

这导致

的输出
rvalue
lvalue

我不明白 dtor 的输出总是 lvalue 不管我多么努力。虽然我同意接受地址 类似于

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

调用左值重载我不明白为什么我永远无法为 dtor 获得 rvalue 的输出。

我觉得这很奇怪,因为对象首先是右值,并且在被破坏之前以某种方式绑定到左值。怎么回事?

this是纯右值,而*this是左值,自然会调用左值引用限定符:

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

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

注意:调用this->等同于调用(*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();
}

打印:

rvalue
x lvalue
lvalue
x lvalue

如果出于某种原因,您真的想调用右值函数,您可以将 this 指针转换为右值引用:

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

或使用std::move:

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