隐式对象参数和 this 指针
implicit object parameter and this pointer
参考Non-static member functions,在
下
const-, volatile-, and ref-qualified member functions
提到:
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.
在这种情况下,the implicit object parameter
和 *this
有什么区别?
我认为区别可以用下面的例子来说明:
当重载决议选择依赖于 CV 限定符时 *this
将具有适当的 CV 限定符,就像隐式对象参数一样:
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());
然而,当重载决议选择依赖于右值/左值引用限定符时,即使隐式对象参数是右值引用并且对象本身是右值,*this
仍将是左值:
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());
注意:在 class 范围内调用函数而不显式使用 this
指针(如 return Probe();
)将使用 隐含对象参数 (这与 (*this)
) 相同,不应与 隐式对象参数 (它只是重载解析期间使用的成员函数签名的不可见部分)混淆。
ref 限定符允许基于表达式引用类型的函数重载。
由于在 C++ 中没有指向引用的指针(或引用)this
不能指向(n 个右值)引用,所以 *this
不能是右值。
一旦函数被调用,右值、左值和引用(有意地)失去它们的相关性。
参考Non-static member functions,在
下const-, volatile-, and ref-qualified member functions
提到:
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.
在这种情况下,the implicit object parameter
和 *this
有什么区别?
我认为区别可以用下面的例子来说明:
当重载决议选择依赖于 CV 限定符时 *this
将具有适当的 CV 限定符,就像隐式对象参数一样:
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());
然而,当重载决议选择依赖于右值/左值引用限定符时,即使隐式对象参数是右值引用并且对象本身是右值,*this
仍将是左值:
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());
注意:在 class 范围内调用函数而不显式使用 this
指针(如 return Probe();
)将使用 隐含对象参数 (这与 (*this)
) 相同,不应与 隐式对象参数 (它只是重载解析期间使用的成员函数签名的不可见部分)混淆。
ref 限定符允许基于表达式引用类型的函数重载。
由于在 C++ 中没有指向引用的指针(或引用)this
不能指向(n 个右值)引用,所以 *this
不能是右值。
一旦函数被调用,右值、左值和引用(有意地)失去它们的相关性。