我想要一份清单。列表中的条目将存储值以及迭代器到列表中的另一个条目。我该如何定义这种类型?它是这样的,但在语法上是正确的。
typedef list<pair<int, MyList::const_iterator>> MyList;
答案 0 :(得分:8)
让我们用一堆用户定义的类型来彻底解决问题,以打破声明的递归:
struct Node {
int _value;
std::list<Node>::const_iterator _next;
};
如果你想使用typedef,你可以:
struct Node;
typedef std::list<Node> NodeList;
struct Node {
int _value;
NodeList::const_iterator _next;
};
编辑作为T.C.提醒我,实例化具有不完整类型的标准容器可能 未定义行为(某些标准库实现确保不是这样)。 所以,让我们把所有这些推迟到以后。
修改:嗯,这也无济于事。因此,请验证您的std::list
实现是否支持不完整的类型(或信任它,这通常是诚实的),或使用Boost :: containers。
template <class = void>
struct Node_ {
int _value;
typename std::list<Node_>::const_iterator _next;
};
typedef Node_<> Node;
答案 1 :(得分:1)
列表中的迭代器不仅不会被插入或删除的其他元素无效,而且迭代器指向的元素也将保持不变。因此我们可以做到:
struct Element {
int first;
Element* second;
};
typedef list<Element> MyList;
这与您的要求非常相似,但second
是指针而不是迭代器。如果你真的需要它作为迭代器,我们可以为std::list<>
切换boost::intrusive::list<>
(如果你不能使用Boost,可以为本土的侵入列表)。然后,value_type
(即Element
)实际上将包含prev / next指针,您可以将其用作迭代器。在Boost中,这个名为iterator_to()
,在此解释:http://www.boost.org/doc/libs/1_43_0/doc/html/intrusive/obtaining_iterators_from_values.html
答案 2 :(得分:0)
如果你愿意,你可以这样做:
typedef list<pair<int, void*> > MyList;
typedef list<pair<int, void*> >::const_iterator MyListIterator;
int main() {
MyList l;
MyListIterator it;
pair<int, void*> p(2, &it);
l.push_back(p);
}
顺便说一下,我更喜欢John Zwinck的解决方案。
答案 3 :(得分:0)
您可以通过向前声明您的元素来实现这一点。
#include <list>
struct Element;
typedef std::list<Element> ElementList;
struct Element
{
int value;
ElementList::iterator element;
};
int main() {
ElementList l;
l.push_back({0, l.end()});
l.push_back({1, l.begin()});
}
答案 4 :(得分:0)
使用boost::any
或同等商品来存储iterator
。由于迭代器往往很小,小对象优化会起作用,而开销也会很低。