2016-09-19 6 views
0

グラフ内のすべてのノード値を列挙するための偽イテレータを作成しようとしています。グラフは、シーケンスがグラフ内のすべてのノードとノードのみからなる限り、任意のシーケンスで抽象化することができます。変更可能な修飾子がなければならず、4つの操作の実装は短く、関数ごとに1行しかないはずです。グラフ内のすべてのノード値を列挙する偽イテレータ操作

4つの偽イテレータ操作のためのテストケースを以下のように、偽イテレータ操作を介してグラフノードの値の文字列を出力するはずである。

gdwg::Graph<std::string,int>> g 
    for (g.begin(); !g.end(); g.next()) 
     std::cout << g.value() << std::end; 

Iのようなグラフを宣言次の次のよう

template <typename N, typename E> class Graph { 

private: 
    struct Node; 
    struct Edge; 

    struct Node { 
     N val_; 
     int numEdges_; 
     int numIncomingEdges_; 
     std::set<std::shared_ptr<Edge>> edges_; 
     std::set<std::shared_ptr<Edge>> incomingEdges_; 
     Node() {} 
     Node(const N x) : val_{x} { numEdges_=0; numIncomingEdges_=0; } 
     void printNode(N n); 
     ~Node(); 
     void update(); 
    }; 

    struct Edge { 
     std::weak_ptr<Node> orig; 
     std::weak_ptr<Node> dest; 
     E val_; 
     Edge(std::shared_ptr<Node> o, std::shared_ptr<Node> d, E x); 
     Edge() {}; 
     void printEdge(); 
     ~Edge(); 
    }; 

    // fake iterator operations 
    void begin() const; 
    bool end() const; 
    void next() const; 
    const N& value() const; 



public: 

    friend class Node_Iterator<N, E>; 
    friend class Edge_Iterator<N, E>; 


private: 
    std::map< N, std::shared_ptr<Node> > nodes_; 

    // fake iterator to be used for the four operations begin(), end(), next() and value() 
    mutable typename std::map< N, std::shared_ptr<Node> >::iterator fakeIter_; 

}; 

4つの操作の実装は、次のとおり

// void begin() const: Sets an internal iterator, i.e., ``pointer'' to the first element of a sequence. 
template <typename N, typename E> 
void Graph<N,E>::begin() const { 
    // gets iterator to the first key/value pair in map sequence 
    fakeIter_ = nodes_.begin(); 
} 

// bool end() const: Returns true if the iterator goes past the last element of the sequence and false otherwise. 
template <typename N, typename E> 
bool Graph<N,E>::end() const { 
    // return true if iterator goes past last element, otherwise return false 
    return ((fakeIter_ == nodes_.end()) ? true : false); 
} 

// void next() const: Moves the iterator to the next element of the sequence. 
template <typename N, typename E> 
void Graph<N,E>::next() const { 
    fakeIter_ = std::next(fakeIter_, 1); 
} 

// const N& value() const: Returns the value of the node pointed to by the iterator. 
template <typename N, typename E> 
const N& Graph<N,E>::value() const { 
    return fakeIter_->second->val_; 
} 

私がコンパイルしようとすると、いくつかのエラーがポップアップしています。私はちょうど私が偽の反復子操作を正しく実装しているかどうか、そして必要ならばそれを改善する方法があれば疑問に思っています。その最初のエラーが言っている何

tests/Graph.tem: In instantiation of ‘void gdwg::Graph<N, E>::begin() const [with N = unsigned int; E = int]’: 
tests/test13.cpp:23:15: required from here 
tests/Graph.tem:713:12: error: no match for ‘operator=’ (operand types are ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::iterator {aka std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’ and ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’) 
    fakeIter_ = nodes_.begin(); 

In file included from /usr/local/include/c++/6.1.0/map:60:0, 
       from tests/Graph.h:19, 
       from tests/test13.cpp:3: 
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: candidate: constexpr std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >& std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >::operator=(const std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&) 
    struct _Rb_tree_iterator 
      ^~~~~~~~~~~~~~~~~ 
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: no known conversion for argument 1 from ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’ to ‘const std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&’ 
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: candidate: constexpr std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >& std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >::operator=(std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&&) 
/usr/local/include/c++/6.1.0/bits/stl_tree.h:174:12: note: no known conversion for argument 1 from ‘std::map<unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node>, std::less<unsigned int>, std::allocator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > > >::const_iterator {aka std::_Rb_tree_const_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >}’ to ‘std::_Rb_tree_iterator<std::pair<const unsigned int, std::shared_ptr<gdwg::Graph<unsigned int, int>::Node> > >&&’ 

答えて

1

は、あなたのbegin関数であるようconstnodes_.begin()const_iteratorを返します、ということです。これは、fakeIter_のタイプiteratorに割り当てることはできません。

あなたは、beginからconstを削除fakeIter_の種類を変更、または(beginがvoid、イテレータを返す必要がありません)あなたの実装を変更する必要があります。

+0

私はconstからbeginを削除することはできませんし、実装の戻り値の型をvoidからiteratorに変更することはできません。だから私ができる唯一のことは、あなたが言ったことに基づいて、偽のタイプを変えることです。どうすれば変更できますか? – iteong

+0

ああ私はそれを笑いました。 :: iteratorを:: const_iteratorに変更するだけです。 – iteong

関連する問題