我已经获得了一些C ++代码,它具有以下结构的列表/迭代器。
typedef struct{
int x;
int y;
}my_struct;
std::list<my_struct> the_list;
std::list<my_struct>::iterator the_iter = the_list.begin();
然后代码以这种方式访问the_iter
的x和y:
(*the_iter).x;
(*the_iter).y;
我想将这些更改为更易阅读的版本:
the_iter->x;
the_iter->y;
从我的C角度来看,这对于指针解除引用来说完全没问题。迭代器也是如此吗?我的同事是否有理由使用(*pointer).
代替p->
答案 0 :(得分:6)
考虑到一般情况,可能会发生一些迭代器类没有提供operator ->
,并且执行(*it).x
将是唯一可行的方法。另一种可能性是operator *
和operator ->
具有一些非标准语义并且不可互换。但是,此类将无法满足任何迭代器概念,并且从技术上讲,它不会是迭代器。
在您的情况下,std::list<T>::iterator
为it->x
和(*it).x
等效。
答案 1 :(得分:5)
这个答案有一个背景,说明为什么两个方法都存在于指针中,如果它们达到同样的目的:https://stackoverflow.com/a/6632474/3113508
对于STL迭代器,您的更改将非常好(并且可能是大多数人喜欢的),原因与->
运算符通常优先用于指针一样。
但是,请注意,可以重载一元*
运算符和->
运算符,以在用户定义的类中提供语义上不同的行为。因此,可能有人可能会选择以不同的方式使用*
或->
,以使foo->bar
不再与(*foo).bar
相同。确保您熟悉所使用的类的文档。
答案 2 :(得分:2)
不,样式偏好/ ->
的知识是他们使用(* a).
vs ->
的唯一原因。
答案 3 :(得分:1)
不同之处在于,operator->
可以重载以返回多个级别的代理对象,并重载operator->
然后再次递归应用,直到返回普通指针,如{{3} }}
operator.
无法在C ++中重载。
该论文的例子是:
#include<iostream>
using namespace std;
void prefix() { cout<< "prefix"; }
void suffix() { cout<< " suffix\n"; }
template<class T>
class Call_proxy{
T* p;
public:
Call_proxy(T* pp) :p(pp){ }
˜Call_proxy() { suffix() ; }
T* operator->() { return p; }
};
template<class T>
class Wrap{
T* p;
public:
Wrap(T* pp) :p(pp) { }
Call_proxy<T> operator->() { prefix() ; return Call_proxy<T>(p) ; }
};
class X{ // one user class
public:
X() { cout<< "make an X\n"; }
int f() const{ cout<< "f()"; return 1; }
void g() const{ cout<< "g()"; }
};
class Y{ // another user class
public:
Y() { cout<< "make a Y\n"; }
void h() const{ cout<< "h()"; }
};
int main() // simple test code
{
Wrap<X> xx(new X) ;
Wrap<Y> yy(new Y) ;
if(xx->f()) cout<< "done\n";
xx->g() ;
yy->h() ;
return 0;
}
xx
和yy
的每次调用都被一对prefix()/ suffix()调用括起来,所以程序产生了:
make an X
make a Y
prefix f() suffix
done
prefix g() suffix
prefix h() suffix