有什么充分的理由C++不允许将 -> 运算符加倍吗?

Is there any good reason C++ doesn't permit doubling the -> operator?

本文关键字:gt 运算符 什么 理由 不允许 C++      更新时间:2023-10-16

在c++中,可以将间接操作符双加:

vector<unique_ptr<string>> arr{make_unique<string>("Test")};
cout << **arr.begin() << endl;

但是不能双引用操作符

cout << arr.begin()->->c_str() << endl;

相反,您必须解决这个(IMO)不太清晰的替代方案:

cout << (*arr.begin())->c_str() << endl;

operator->是返回指针类型的一元操作符,因此可以很自然地将它们链接起来。这种限制有什么好的理由吗?是不是有什么我没发现的解析困难?

编辑

在5.2.5/3中,c++标准规定:

如果E1的类型是"指向类X的指针",那么表达式E1->E2是转换为等效形式(*(E1))。E2

我只是希望它被指定为:

如果E1的类型是"指向类X的指针",那么表达式E1->是转换为等效形式(*(E1))。

实际上,包含E1和E2的定义似乎是相反的,因为重载的operator->不是二进制操作符。

这里有一个不太专业的解释。

->(*someptr).memberfunc()*.的简写。因此,这可以表示为someptr->memberfunc()

在您的示例中,两个->将与(*(*arr.begin()).).c_str()相同。注意这个额外的点。这没有意义,也无法编译,因为。是二进制操作符,*是一元操作符。因此,你会有一个"额外"的点。你真的需要两个*,而只有一个.。使用一个->和一个*,就像你所做的。

->表示"解引用并获取成员"。您希望解引用两次,并获得一次成员,因此double ->不是您想要的。

注意:

(*a).b
a->b

等于

a->->b
(*a)->b
(*(*a)).b

作为一个操作符是可以的,但这并不符合->的精神,它的精神是访问结构中指向的东西。我宁愿输入a->b而不是(*a).b

所以,虽然没有技术上的原因,(*a)->b告诉你"a是一个指向b结构的指针的指针",a->b->c完全不同于a->->b,尽管它们看起来很相似。

如果我理解正确,你可以得到你正在寻找一个更好的设计的行为。

解引用操作符实际上不仅仅是一个从指针中检索值的操作符,它提供了稍微复杂一些的行为。

->操作符的业务逻辑在这里有清晰的说明,在这里也有扩展,在这里你可以找到一个关于指针相关操作符的鸟瞰图。

你可以很容易地猜到,如果你有T->t,你可以在你的优势上使用钻取行为,假设你已经正确地设计和定义了T和它自己的->运算符。

这个解决方案可以很容易地为你的应用程序带来一些多态行为。