()"进行成员访问-6ren"> ()"进行成员访问-表达式x->y 要求x 是指向完整类类型的指针,或者当x 是类的实例时, 需要为 x 定义的 operator->()。但是如果是后者,为什么不能我可以使用转换函数来代替(即将对象 x 转换为指针)?-6ren">
gpt4 book ai didi

c++ - 使用 "operator T*()"而不是 "T* operator->()"进行成员访问

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:44:12 29 4
gpt4 key购买 nike

表达式x->y 要求x 是指向完整类类型的指针,或者当x 是类的实例时, 需要为 x 定义的 operator->()。但是如果是后者,为什么不能我可以使用转换函数来代替(即将对象 x 转换为指针)?例如:

struct A
{
int mi;

operator A*() { return this; }
};

int main()
{
A a;

a[1]; // ok: equivalent to *(a.operator A*() + 1);
a->mi; // ERROR
}

这给出了一条错误信息:

错误:“->”的基操作数具有非指针类型“A”

但问题是,为什么它不像 a[1] 那样使用 a.operator A*() 呢?

最佳答案

这是由于表达式中运算符的特殊重载解析规则。对于大多数运算符,如果任一操作数的类型是类或枚举,则运算符函数和内置运算符会相互竞争,并且重载决策将决定使用哪一个。这就是 a[1] 发生的情况。但是,也有一些异常(exception),适用于您的情况的是标准中的 [13.3.1.2p3.3] 段(在所有引号中强调我的):

(3.3) — For the operator ,, the unary operator &, or the operator ->, the built-in candidates set is empty. For all other operators, the built-in candidates include all of the candidate operator functions defined in 13.6 that, compared to the given operator,

  • have the same operator name, and
  • accept the same number of operands, and
  • accept operand types to which the given operand or operands can be converted according to 13.3.3.1, and
  • do not have the same parameter-type-list as any non-member candidate that is not a function template specialization.

因此,对于 a[1],用户定义的转换用于获取可以应用内置 [] 运算符的指针,但是对于上面的三个异常(exception),首先只考虑运算符函数(在这种情况下没有任何)。稍后,[13.3.1.2p9]:

If the operator is the operator ,, the unary operator &, or the operator ->, and there are no viable functions, then the operator is assumed to be the built-in operator and interpreted according to Clause 5.

简而言之,对于这三个运算符,只有在其他一切都失败时才考虑内置版本,然后它们必须在没有任何用户定义的转换的情况下处理操作数。

据我所知,这样做是为了避免混淆或模棱两可的行为。例如,内置运算符 & 对(几乎)所有操作数都是可行的,因此如果在正常步骤中考虑它们,重载它们将不起作用过载决议。

Operator -> 在重载时有异常行为,因为它会导致重载 -> 的调用链,如 [注释 129] 中所述:

If the value returned by the operator-> function has class type, this may result in selecting and calling another operator-> function. The process repeats until an operator-> function returns a value of non-class type.

我想你可能会从一个重载 -> 的类开始,它返回另一个类类型的对象,它不会重载 ->但是有一个用户定义的指针类型转换,导致内置 -> 的最终调用被认为有点太困惑了。将此限制为 -> 的显式重载看起来更安全。


所有引述均来自当前工作草案 N4431,但相关部分自 C++11 以来未发生变化。

关于c++ - 使用 "operator T*()"而不是 "T* operator->()"进行成员访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30123338/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com