有什么好的理由C ++不允许加倍 - >运营商?

时间:2014-05-07 11:20:42

标签: c++

在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-&gt;是   转换为等效形式(*(E1))。

这个定义实际上似乎与E1和E2相反,因为重载的operator->不是二元运算符。

3 个答案:

答案 0 :(得分:1)

这是一个不太技术性的解释。

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

在您的示例中,两个->(*(*arr.begin()).).c_str()相同。注意额外的点。这没有意义,也没有编译,因为。是二元运算符,*是一元运算符。因此,你会有一个“额外”点。你真的想要两个*和一个.。正如您所做的那样,使用一个->和一个*

->表示“取消引用并获得会员”。你想要取消引用两次,并获得一次成员,所以双->不是你想要的。

答案 1 :(得分:0)

请注意:

(*a).b
a->b

是同样的事情

所以

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

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

因此,虽然没有技术原因(*a)->b告诉您&#34; a是指向b&#34;的结构指针的指针。并且a->b->c 完全 a->->b不同,即使它们看起来相似。

答案 2 :(得分:0)

如果我理解正确,您可以通过更好的设计获得您正在寻找的行为。

dereference运算符实际上并不像从一个指针检索值的运算符那样真正起作用,如果提供稍微复杂的行为。

->运算符的业务逻辑显然是illustrated here,它也正在展开herehere,您可以找到有关指针相关运算符的鸟瞰图here

正如您可以轻易猜到的那样,如果您有T->t,您可以利用自己的优势,假设您已经正确设计并定义了T及其自己的->运算符

这是一个可以轻松为您的应用程序带来一些多态行为的解决方案。