我对实现自定义类的迭代器很困惑。我正在尝试为std :: set实现一个迭代器,我的Vertex类被声明为:
class Vertex{
public:
int i, j;
std::set<Vertex*> adj; //references to adjacent vertices
Vertex();
~Vertex();
//end constructors
/** must overload for set<Vertex> to function */
const bool operator < (const Vertex &o) const;
};//END class Vertex
但如果我定义
iterator<Vertex*> begin(){
return iterator<Vertex*>( *this, 0 );
}
iterator>Vertex*> end(){
return iterator<Vertex*>( *this, sizeof(Vertex) );
}
所以我希望迭代如下:
set<Vertex*>::iterator it;
//for all vertices adjacent of cur
for(it = cur.begin(); it != cur.end(); it++){
//...
}
并收到这些错误:
In file included from Vertex.cc:8:0:
Vertex.h:50:22: error: wrong number of template arguments (1, should be 5)
std::iterator<Vertex*> begin();
^
In file included from c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_algoba
se.h:65:0,
from c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_tree.h
:61,
from c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\set:60,
from Vertex.h:10,
from Vertex.cc:8:
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_iterator_base_types.h:118:12
: error: provided for 'template<class _Category, class _Tp, class _Distance, cla
ss _Pointer, class _Reference> struct std::iterator'
struct iterator
^
In file included from Vertex.cc:8:0:
Vertex.h:50:31: error: invalid type in declaration before ';' token
std::iterator<Vertex*> begin();
^
Vertex.h:51:22: error: wrong number of template arguments (1, should be 5)
std::iterator<Vertex*> end();
<additional errors>
ss _Pointer, class _Reference> struct std::iterator'
struct iterator
^
Vertex.cc:114:29: error: invalid use of 'this' in non-member function
return iterator<Vertex*>( *this, 0 );
^
Vertex.cc: At global scope:
Vertex.cc:116:1: error: invalid use of template-name 'std::iterator' without an
argument list
iterator>Vertex*> end(){
^
Vertex.cc: In function 'int begin()':
Vertex.cc:115:1: warning: control reaches end of non-void function [-Wreturn-typ
e]
}
^
make: *** [Vertex.o] Error 1
我需要帮助弄清楚如何去做这件事;我发现大多数教程/链接也令人困惑。注意:我没有使用C ++ 11
答案 0 :(得分:3)
这里涉及两个步骤:
iterator
课程中提供名为Vertex
的类型。begin
和end
以正确使用该迭代器类型。由于您希望在此处迭代底层set
,所以让您的Vertex
类导出的迭代器类型为set提供的迭代器类型。你可以写
class Vertex{
public:
int i, j;
std::set<Vertex*> adj; //references to adjacent vertices
Vertex();
~Vertex();
//end constructors
/** must overload for set<Vertex> to function */
const bool operator < (const Vertex &o) const;
typedef std::set<Vertex*>::iterator iterator;
iterator begin();
iterator end();
};//END class Vertex
现在,我们可以按如下方式定义begin
和end
:
Vertex::iterator Vertex::begin() {
return adj.begin();
}
Vertex::iterator Vertex::end() {
return adj.end();
}
现在可以编写
之类的内容Vertex v = /* ... */;
for (Vertex::iterator itr = v.begin(); itr != v.end(); ++itr) {
/* ... */
}
或
Vertex v = /* ... */
for (auto& adj: v) {
/* ... */
}
虽然我们正在努力,但你可以清理这段代码。对于初学者,您可能不应该公开i
,j
和adj
;这违反了封装原则。将这些数据成员设为私有,并提供成员函数来访问这些值。
这里的另一个细节是你实际上不需要在这里定义operator<
。如果要在operator<
内直接存储给定类型的对象或set
中的键,则需要定义map
,但这里存储指针到Vertex
和set
内的map
。因此,除非您确实希望以后可以使用operator<
,否则我不会担心定义operator<
。你可以删除它。
希望这有帮助!
答案 1 :(得分:1)
我相信您正在寻找的迭代器类型为std::set<Vertex*>::iterator
并且只需begin
获取end
和set
cur.adj.begin()
cur.adj.end()
}和void func(Vertex* cur)
{
if(cur == NULL)
return;
for(std::set<Vertex*>::iterator it = cur->adj.begin(); it != cur->adj.end(); ++it)
{
//Do something
}
}
。
示例:
cur.begin()
但是,如果您坚持将代码实现为cur.end()
和begin
,则一种方法是为您的类实现end
和std::set<Vertex*>::iterator begin()
{
return adj.begin();
}
std::set<Vertex*>::iterator end()
{
return adj.end();
}
函数。< / p>
{{1}}