请告诉我如何为std :: list的迭代器定义operator->(),以便引用迭代器指向的元素的成员。
编辑:
问题在于,如果你这样实现(Fred Nurk):
template<class T>
struct list {
private:
struct Node { // internal class that actually makes up the list structure
Node *prev, *next;
T data;
};
public:
struct iterator { // iterator interface to the above internal node type
T* operator->() const {
return &_node->data;
}
private:
Node *_node;
}
};
然后当你写:
struct A {
int n;
};
void f() {
list<A> L; // imagine this is filled with some data
list<A>::iterator x = L.begin();
x->n = 42;
}
然后
x-&gt; n我理解像x-&gt; operator-&gt;()n,它等同于(A ponter to a)n,它是一个非。如何理解这一部分。一些答案表明它相当于x-&gt; operator-&gt;() - &gt; n; (而不是x-&gt; operator-&gt;()n)但我不明白为什么。 请解释一下。
答案 0 :(得分:3)
(提示:它返回一个指向元素的指针。)
答案 1 :(得分:3)
->
运算符的行为如下:
T->x; // some field
T->foo(); // some function
......相当于:
T.operator->()->x;
T.operator->()->foo();
请注意将->
重新应用于返回的内容。
答案 2 :(得分:2)
运算符->
的实现方式与C ++中的其他运算符不同。操作符函数应返回指针,->
再次应用于该指针。
答案 3 :(得分:2)
随着许多细节的消失,以下是它如何运作的要点:
template<class T>
struct list {
private:
struct Node { // internal class that actually makes up the list structure
Node *prev, *next;
T data;
};
public:
struct iterator { // iterator interface to the above internal node type
T* operator->() const {
return &_node->data;
}
private:
Node *_node;
}
};
因此,给定:
struct A {
int n;
};
void f() {
list<A> L; // imagine this is filled with some data
list<A>::iterator x = L.begin();
x->n = 42;
// x.operator->() returns an A*
// which gets -> applied again with "n"
}
答案 4 :(得分:1)
返回指针。为了完整起见,这是一个简单的例子:
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class SafeVectorIterator
{
vector<T> & _vec;
size_t _pos;
public:
SafeVectorIterator(vector<T> & vec) : _vec(vec), _pos(0) { }
void operator++() { ++_pos; }
void operator--() { --_pos; }
T& operator*() { return _vec.at(_pos); }
T* operator->() { return &_vec.at(_pos); }
};
struct point { int x, y; };
int main()
{
vector<point> vec;
point p = { 1, 2 };
vec.push_back(p);
vec.push_back(p);
SafeVectorIterator<point> it(vec);
++it;
it->x = 8;
cout << (*it).y << '\n';
return 0;
}