混淆重载rvalues和左值的成员函数

时间:2016-06-22 19:59:57

标签: c++ lvalue rvalue overload-resolution

我有以下设置:

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的输出。

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

1 个答案:

答案 0 :(得分:0)

this是prvalue,但*this是左值,自然会调用左值ref-qualifiers:

§ 5.3.1 Unary operators [expr.unary.op]
  

一元*运算符执行间接:应用它的表达式应该是一个指向它的指针   对象类型或指向函数类型的指针,结果是引用对象或函数的左值   表达点指向的地方。

来自cppreference,this pointer

  

当在允许使用this关键字的任何上下文中使用非静态类成员时(非静态成员函数体,成员初始化列表,默认成员初始值设定项),隐式this-&gt;在名称之前自动添加,导致成员访问表达式(如果成员是虚拟成员函数,则会导致虚函数调用)。

注意:调用this-&gt;相当于调用(* 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( ); }