然后迭代器取消引用"。"算子与。 " - >"操作者

时间:2015-04-22 21:16:27

标签: c++ listiterator

我已经获得了一些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->

4 个答案:

答案 0 :(得分:6)

考虑到一般情况,可能会发生一些迭代器类没有提供operator ->,并且执行(*it).x将是唯一可行的方法。另一种可能性是operator *operator ->具有一些非标准语义并且不可互换。但是,此类将无法满足任何迭代器概念,并且从技术上讲,它不会是迭代器。

在您的情况下,std::list<T>::iteratorit->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;
}

xxyy的每次调用都被一对prefix()/ suffix()调用括起来,所以程序产生了:

make an X
make a Y
prefix f() suffix
done
prefix g() suffix
prefix h() suffix