使用函数模板将迭代器返回到图节点
Returning an iterator to graph node with function templates
我有 2 个文件,一个是 .h 文件,其中包含我的声明,另一个是 .tem 文件,其中包含我的 .h 文件的实现。我的图节点迭代器的 begin() 和 end() 的迭代器有问题(如下所示“// 图节点的迭代器”),它应该 return 指向开始的迭代器或迭代图的结尾。
以下是我在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() 的错误代码,因为 end() 错误类似):
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 {
^~~~~~~~~~~
于是照着说的做了,在Graph前面加了"typename",也做成了模板。但它却出现了这个错误:
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;
^~~~~
所以我删除了 begin() 前面的图表,因为我认为这是问题所在,但得到了另一个错误:
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 {
^~~~~
谁能告诉我哪里做错了?
Node_Iterator
不是 Graph
的子 class,因此无法找到 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_);
}
我有 2 个文件,一个是 .h 文件,其中包含我的声明,另一个是 .tem 文件,其中包含我的 .h 文件的实现。我的图节点迭代器的 begin() 和 end() 的迭代器有问题(如下所示“// 图节点的迭代器”),它应该 return 指向开始的迭代器或迭代图的结尾。
以下是我在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() 的错误代码,因为 end() 错误类似):
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 {
^~~~~~~~~~~
于是照着说的做了,在Graph前面加了"typename",也做成了模板。但它却出现了这个错误:
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;
^~~~~
所以我删除了 begin() 前面的图表,因为我认为这是问题所在,但得到了另一个错误:
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 {
^~~~~
谁能告诉我哪里做错了?
Node_Iterator
不是 Graph
的子 class,因此无法找到 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_);
}