隐式对象参数和 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 不能是右值。

一旦函数被调用,右值、左值和引用(有意地)失去它们的相关性。