2016-09-12 2 views
0

У меня есть 2 файла, один файл .h, который содержит мои объявления, а другой - .tem-файл, который содержит реализацию моего .h-файла. У меня возникают проблемы с итератором для begin() и end() для моего итератора узла графа (показано ниже в разделе «// Итераторы для узлов графа»), который должен возвращать итератор, указывающий на начало или конец итерированный график.Возвращение итератора к узлу графа с шаблонами функций

Ниже мой код в Graph.h:

#ifndef _Graph_h 
#define _Graph_h 

#include <vector> 
#include <algorithm> 
#include <string> 
#include <memory> 
#include <iostream> 
#include <exception> 
#include <map> 
#include <set> 
#include <typeinfo> 


namespace gdwg { 

    template <typename N, typename E> class Graph; // function prototype for Graph class 

//----------------------------------------------------------- 
// Iterators for Graph with Nodes N and Edges E 
//----------------------------------------------------------- 

    // Iterator class for Node N 
    template <typename N, typename E> class Node_Iterator { 

    ******* Some code for public and private members of Node_Iterator 

    }; 

    // Iterator class for Edge E 
    template <typename N, typename E> class Edge_Iterator { 

    ******* Some code for public and private members of Edge_Iterator 

    }; 

template <typename N, typename E> class Graph { 

    private: 
     struct Node; 
     struct Edge; 

     struct Node { 
      N val_; 
      int numEdges_; 
      std::set<std::shared_ptr<Edge>> edges_; 
      Node() {} 
      Node(const N x) : val_{x} { numEdges_=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(); 
     }; 

    public: 

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


     ******* Some code for public members of Graph 

     // Iterators for Graph nodes 
     Node_Iterator<N, E> begin() const; 

     Node_Iterator<N, E> end() const; 


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


}; 

    #include "Graph.tem" // definition and implementation of Node_Iterator, Edge_Iterator and Graph classes 

} 

#endif 

Это определение в файле .tem для итераторов:

template <typename N, typename E> 
Graph<N, E>::Node_Iterator<N, E> Graph<N, E>::begin() const { 
    return Node_Iterator<N, E>(&Graph<N, E>::nodes_); 
} 

template <typename N, typename E> 
Graph<N, E>::Node_Iterator<N, E> Graph<N, E>::end() const { 
    return Node_Iterator<N, E>(nullptr); 
} 

Когда я попытался скомпилировать его, там был следующим кодом ошибки (я просто поставлю код ошибки для begin() coz ошибка конца() аналогична):

tests/Graph.tem:336:14: error: non-template ‘Node_Iterator’ used as template 
Graph<N, E>::Node_Iterator<N, E> Graph<N, E>::begin() const { 
       ^~~~~~~~~~~~~ 
tests/Graph.tem:336:14: note: use ‘gdwg::Graph<N, E>::template Node_Iterator’ to indicate that it is a template 
tests/Graph.tem:336:1: error: need ‘typename’ before ‘gdwg::Graph<N, E>::Node_Iterator’ because ‘gdwg::Graph<N, E>’ is a dependent scope 
Graph<N, E>::Node_Iterator<N, E> Graph<N, E>::begin() const { 
^~~~~~~~~~~ 

Итак, я сделал то, что он сказал, и добавил «typename» перед Graph, а также сделал его шаблоном. Но придумал эту ошибку вместо:

tests/Graph.tem:336:52: error: prototype for ‘typename gdwg::Graph<N, E>::Node_Iterator<N, E> gdwg::Graph<N, E>::begin() const’ does not match any in class ‘gdwg::Graph<N, E>’ 
typename Graph<N, E>::template Node_Iterator<N, E> Graph<N, E>::begin() const { 
                ^~~~~~~~~~~ 
In file included from tests/test1.cpp:3:0: 
tests/Graph.h:322:23: error: candidate is: gdwg::Node_Iterator<N, E> gdwg::Graph<N, E>::begin() const 
    Node_Iterator<N, E> begin() const; 
         ^~~~~ 

Так я извлекал график перед начать(), как я думал, что это проблема, но получил другую ошибку вместо того, чтобы:

tests/Graph.tem:336:60: error: non-member function ‘typename gdwg::Graph<N, E>::Node_Iterator<N, E> gdwg::begin()’ cannot have cv-qualifier 
typename Graph<N, E>::template Node_Iterator<N, E> begin() const { 
                  ^~~~~ 

Может кто-то скажи мне, что я делаю неправильно?

+0

Где ваш класс «график»? Я могу видеть определения функции-члена класса, но где это объявления? – Hayt

+0

Его объявления находятся в файле .h, а его определения содержатся в файле .tem. Определения файлов .tem определяют только те функции, у которых есть код реализации. – iteong

+0

Ах, извините. Оказалось, что так или иначе. – Hayt

ответ

1

Node_Iterator не является подклассом Graph, поэтому Graph<N, E>::Node_Iterator<N, E> не найдено. Просто измените определение на это должно работать:

template <typename N, typename E> 
Node_Iterator<N,E> Graph<N,E>::begin() const { 
    return Node_Iterator<N,E>(&Graph<N, E>::nodes_); 
} 
+0

У меня возникли следующие ошибки: tests/Graph.tem: 342: 12: error: нет соответствующей функции для вызова в 'gdwg :: Node_Iterator :: Node_Iterator (std :: map :: Node>, std :: less , std :: allocator :: Node>>>> gdwg :: Graph :: *) ' return Node_Iterator (& Graph :: nodes_); – iteong

+0

tests/Graph.tem: 80: 1: note: кандидат: gdwg :: Node_Iterator :: Node_Iterator (const std :: map :: Node>> *) [с N = int; E = int; typename gdwg :: Graph :: Node = gdwg :: Graph :: Node] Node_Iter ator :: Node_Iterator (const std :: map > * nodes) { ^ ~~~~~~~~~~~~~~~~~ – iteong

+0

В файл, включенный в тесты /test1.cpp:3:0: tests/Graph.h: 33: 42: note: кандидат: gdwg :: Node_Iterator :: Node_Iterator (const gdwg :: Node_Iterator &) шаблон <имя-типа N, имя-E> класс Node_Iterator { ^ ~~~~~~~~~~~~ – iteong

Смежные вопросы