C ++ std :: set <vertex> iterator with custom Vertex class </vertex>

时间:2015-01-04 16:13:38

标签: c++ iterator

我对实现自定义类的迭代器很困惑。我正在尝试为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

2 个答案:

答案 0 :(得分:3)

这里涉及两个步骤:

  1. 您需要在iterator课程中提供名为Vertex的类型。
  2. 然后,您需要定义beginend以正确使用该迭代器类型。
  3. 由于您希望在此处迭代底层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
    

    现在,我们可以按如下方式定义beginend

    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) {
       /* ... */
    }
    

    虽然我们正在努力,但你可以清理这段代码。对于初学者,您可能不应该公开ijadj;这违反了封装原则。将这些数据成员设为私有,并提供成员函数来访问这些值。

    这里的另一个细节是你实际上不需要在这里定义operator<。如果要在operator<内直接存储给定类型的对象或set中的键,则需要定义map,但这里存储指针Vertexset内的map。因此,除非您确实希望以后可以使用operator<,否则我不会担心定义operator<。你可以删除它。

    希望这有帮助!

答案 1 :(得分:1)

我相信您正在寻找的迭代器类型为std::set<Vertex*>::iterator并且只需begin获取endset 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,则一种方法是为您的类实现endstd::set<Vertex*>::iterator begin() { return adj.begin(); } std::set<Vertex*>::iterator end() { return adj.end(); } 函数。< / p>

{{1}}