C++ 成员访问/间接运算符等价

标签 c++ pointers language-lawyer

我正在查看有关成员引用运算符(一元 * 取消引用运算符、-> 成员访问运算符)的 C++ 标准以及许多其他相关问题:

C++ - Difference between (*). and ->?

ptr->hello(); /* VERSUS */ (*ptr).hello();

C++ pointers difference between * and ->

我看到大多数答案都指出 p->m 是 C++ 标准定义的 (*p).m 的语法糖(5.2.5,段落2):

The expression E1->E2 is converted to the equivalent form (*(E1)).E2

很多评论还指出,因为operator*operator->在类中是可重载的,所以应该统一重载以确保一致的行为。

这些陈述似乎相互矛盾:如果(根据标准)E1->E2 转换为等效形式 (*(E1)).E2 ,那么重载 operator-> 的目的是什么(标准允许)?

更简单地说,标准的这两部分是否有冲突,还是我误解了标准?
E1->E2(*(E1)).E2 的等价转换适用于所有完整类型还是仅适用于内置类型?

最佳答案

E1 -> E2(*(E1)).E2 的转换仅适用于原始指针类型。对于类类型,E1 -> E2 的计算结果为 (E1).operator->().E2,这可能会递归地扩展出更多的 operator 拷贝-> 如果 operator-> 的返回类型本身不是指针类型。您可以通过创建一个支持 operator* 但不支持 operator-> 的类型并尝试在其上使用箭头运算符来看到这一点;你会得到一个错误,提示 operator-> 未定义。

作为后续行动,通常根据 operator * 实现 operator ->,使 -> 具有语义code> 匹配指针的语义。你经常会看到这样的事情:

PointerType ClassType::operator-> () const {
    return &**this;
}

这个表达式被解释为

&(*(*this)),

意思是“获取这个对象 (*this),解引用它 (*(*this)),然后得到你找到的地址 (& (*(*this)).)"现在,如果您使用 E1 -> E2 应该等同于 (*(E1)).E2 的规则,您会发现您最终得到了等价的东西。

关于C++ 成员访问/间接运算符等价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35756466/

相关文章:

c++ - 如何将 boost::lambda 与 std::find_if 一起使用?

c、指针和 printf 的参数列表。使困惑

c - 矩阵作为C中的双指针,如何移动它

c++ - 是否可以在 using 声明中引用用户定义的转换模板?

python - python 中 C++ const-reference 复制构造函数参数的等价物是什么

c++ - tbb::parallel_for 将 ‘const value_type’ 作为 ‘this’ 参数传递会丢弃限定符

c++ - 无法使用点布局(graphviz 作为库)

c++ - 如何检查网站是否包含 Flash

c++ - 对 C++ 中的指针有几个疑问?

c++11 - clang++失败,但g++成功在赋值中使用强制转换为const-unrelated-type运算符