在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->
不是二元运算符。
答案 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,它也正在展开here,here,您可以找到有关指针相关运算符的鸟瞰图here。
正如您可以轻易猜到的那样,如果您有T->t
,您可以利用自己的优势,假设您已经正确设计并定义了T
及其自己的->
运算符
这是一个可以轻松为您的应用程序带来一些多态行为的解决方案。