混淆在右值和左值上重载成员函数
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( ); }
我有以下设置:
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( ); }