隐式对象参数和此指针

implicit object parameter and this pointer

提问人:Vinod 提问时间:9/14/2019 最后编辑:Jan SchultkeVinod 更新时间:9/3/2023 访问量:858

问:

关于非静态成员函数,在

const-、volatile- 和 ref-qualified 成员函数

它提到:

非静态成员函数可以声明,没有 ref-qualifier, 使用左值 ref-qualifier(参数列表后面的标记 &)或 右值 ref-qualifier(参数列表后面的标记 &&)。 在过载解决期间,非静态 cv 限定成员函数 X 类的处理方式如下:

no ref-qualifier:隐式对象参数具有对 CV 限定的 X 的类型左值引用,并且还允许绑定右值隐含对象参数

Lvalue ref-qualifier:隐式对象参数的类型为 lvalue 参考 cv 合格的 X

rvalue ref-qualifier:隐式对象参数的类型为 rvalue 参考 cv 合格的 X

注意:与 cv-qualification 不同,ref-qualification 不会更改 此指针的属性:在右值引用限定的范围内 函数,*这仍然是一个左值表达式。

在这种情况下,和 和有什么不一样?the implicit object parameter*this

C++ 方法 非静态 ref-qualifier

评论

0赞 Darklighter 9/14/2019
我把它想象成一旦调用函数,就会删除右值 ref 限定符。可能有一些理由表明,如果没有显式 .*thisstd::move(*this)
0赞 Darklighter 9/14/2019
仅供参考,它是用于成员函数调用的指针,而不是隐式对象参数coliru.stacked-crooked.com/a/3819152edc5a1914this
0赞 Vinod 9/14/2019
@Darklighter猜你的代码只会显示 *this 总是左值?
0赞 Darklighter 9/14/2019
是的,它展示了您引用中的注释,但它也展示了 和 之间没有区别,即它不像第一种形式使用隐式对象参数的类型而不是 的类型来进行重载解析。memfun()(*this).memfun()*this
0赞 user7860670 9/14/2019
@Darklighter 第一种形式使用隐含对象参数,与 相同。(*this)

答:

2赞 user7860670 9/14/2019 #1

我认为可以用以下示例来说明差异:

当重载解析选择依赖于 CV 限定符时,将具有适当的 CV 限定符,就像隐式对象参数一样:*this

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());

注意:在不显式使用指针的情况下在类作用域中调用函数(如 )将使用隐含对象参数(与 相同),不应与隐式对象参数(它只是重载解析期间使用的成员函数签名的不可见部分)混淆。thisreturn Probe();(*this)

评论

0赞 Darklighter 9/14/2019
但是,一旦调用了右值限定成员函数,隐式对象参数的(初始)类型会有什么影响呢?我不认为它有任何。
1赞 user7860670 9/14/2019
@Darklighter我同意,隐式对象参数仅在重载解析期间才重要,以建立完整的函数签名。
0赞 Klaus 9/14/2019
如果写作与.我无法捕捉到 *this 和隐式对象指针之间的区别。你能解释一下吗?return (*this).Probe();return Probe();
1赞 user7860670 9/14/2019
@Klaus 该构造使用隐含对象参数,与 相同。而隐式对象参数是非静态成员函数签名的虚构部分。return Probe()(*this)
2赞 Darklighter 9/14/2019 #2

ref-qualifiers 允许基于表达式的引用类型进行函数重载。

由于 C++ 中没有指向引用的指针(或引用),因此不能指向(n 右值)引用,因此不能是右值。this*this

rvalue、lvalue 和 reference(故意)在调用函数后失去其相关性。