有什么充分的理由C++不允许将 -> 运算符加倍吗?
Is there any good reason C++ doesn't permit doubling the -> operator?
在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
和它自己的->
运算符。
这个解决方案可以很容易地为你的应用程序带来一些多态行为。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 是否需要使用 - &gt;运算符在C 中调用成员函数时