类在模板中找不到内部定义的类C++类
Class cannot find Internally Defined C++ Class inside Template
我有下面的代码,编译器错误是:为什么graph_algorithm图类内找不到顶点类?
graph_algorithms.h:26:33: error: ‘Graph::graph<T>::vertex’ is not a type
graph_algorithms.h:26:55: error: ‘Graph::graph<T>::vertex’ is not a type
graph_algorithms.h: In member function ‘bool Graph::graph_algorithm<T>::vertex_comparer::operator()(int&, int&)’:
graph_algorithms.h:28:10: error: ‘t1’ was not declared in this scope
graph_algorithms.h:28:21: error: ‘t2’ was not declared in this scope
graph_algorithms.h:28:33: error: expected primary-expression before ‘return’
graph_algorithms.h:28:33: error: expected ‘:’ before ‘return’
graph_algorithms.h:28:33: error: expected primary-expression before ‘return’
graph_algorithms.h:28:33: error: expected ‘;’ before ‘return’
graph_algorithms.h:29:7: warning: no return statement in function returning non-void [-Wreturn-type]
#ifndef GRAPH_H_
#define GRAPH_H_
#include <list>
#include <algorithm>
#include <vector>
#include <utility>
#include <iostream>
#include <stdexcept>
#include <assert.h>
namespace Graph
{
template <class T>
class graph
{
// Forward Declarations
private:
class vertex;
class edge;
template <class U>
friend class graph_algorithm;
public :
explicit graph(const std::vector<std::pair<T, T> > &vertices);
~graph()
{}
void insert_vertex_pair_by_keys(T key1, T key2);
const std::list<vertex> &vertices() const {return m_Vertices;}
// Private contained classes
private:
struct edge
{
edge(vertex *edge, T weight) :
m_Edge(edge),
m_Weight(weight)
{}
vertex *m_Edge;
T m_Weight;
}; // END EDGE
class vertex
{
public:
vertex(T key) :
m_Key(key)
{}
void connect_edge(vertex *adjacent);
const T key() const {return m_Key;}
const std::list<edge> &edges() const {return m_Edges;}
private:
std::list<edge> m_Edges;
T m_Key;
bool contains_edge_to_vertex_with_key(const T key);
}; // END VERTEX
// Private methods and member variables
private:
std::list<vertex> m_Vertices;
vertex *contains_vertex(const T key);
};
}
/*!
* Constructor of graph: Take a pair of vertices as connection, attempt
* to insert if not already in graph. Then connect them in edge list
*/
template <class T>
Graph::graph<T>::graph(const std::vector<std::pair<T, T> > &vertices_relation)
{
#ifndef NDEBUG
std::cout << "Inserting pairs: " << std::endl;
#endif
typename std::vector<std::pair<T, T> >::const_iterator insert_it = vertices_relation.begin();
for(; insert_it != vertices_relation.end(); ++insert_it) {
#ifndef NDEBUG
std::cout << insert_it->first << " -- > " << insert_it->second << std::endl;
#endif
/*
* Insert vertex by key pairs into the graph
*/
insert_vertex_pair_by_keys(insert_it->first, insert_it->second);
}
#ifndef NDEBUG
std::cout << "Printing results: " << std::endl;
typename std::list<vertex>::iterator print_it = m_Vertices.begin();
for(; print_it != m_Vertices.end(); ++print_it) {
std::cout << print_it->key() << " --| ";
typename std::list<edge>::const_iterator edge_it = print_it->edges().begin();
for(; edge_it != print_it->edges().end(); ++edge_it) {
std::cout << edge_it->m_Edge->key() << " --> ";
}
std::cout << std::endl;
std::cout << "|" << std::endl;
std::cout << "V" << std::endl;
}
#endif
}
/*!
* Takes in a value of type T as a key and
* inserts it into graph data structure if
* key not already present
*/
template <typename T>
void Graph::graph<T>::insert_vertex_pair_by_keys(T key1, T key2)
{
/*
* Check if vertices already in graph
*/
Graph::graph<T>::vertex *insert1 = contains_vertex(key1);
Graph::graph<T>::vertex *insert2 = contains_vertex(key2);
/*
* If not in graph then insert it and get a pointer to it
* to pass into edge. See () for information on how
* to build graph
*/
if (insert1 == NULL) {
m_Vertices.push_back(vertex(key1));
insert1 = contains_vertex(key1);
}
if (insert2 == NULL) {
if (key1 != key2) {
m_Vertices.push_back(vertex(key2));
}
insert2 = contains_vertex(key2);
}
#ifndef NDEBUG
assert(insert1 != NULL && "Failed to insert first vertex");
assert(insert2 != NULL && "Failed to insert second vertex");
#endif
/*!
* At this point we should have a vertex to insert an edge on
* if not throw an error.
*/
if (insert1 != NULL && insert2 != NULL) {
insert1->connect_edge(insert2);
insert2->connect_edge(insert1);
} else {
throw std::runtime_error("Unknown");
}
}
/*!
* Search the std::list of vertices for key
* if present return the vertex to indicate
* already in graph else return NULL to indicate
* new node
*/
template <typename T>
typename Graph::graph<T>::vertex *Graph::graph<T>::contains_vertex(T key)
{
typename std::list<vertex >::iterator find_it = m_Vertices.begin();
for(; find_it != m_Vertices.end(); ++find_it) {
if (find_it->key() == key) {
return &(*find_it);
}
}
return NULL;
}
/*!
* Take the oposing vertex from input and insert it
* into adjacent list, you can have multiple edges
* between vertices
*/
template <class T>
void Graph::graph<T>::vertex::connect_edge(Graph::graph<T>::vertex *adjacent)
{
if (adjacent == NULL)
return;
if (!contains_edge_to_vertex_with_key(adjacent->key())) {
Graph::graph<T>::edge e(adjacent, 1);
m_Edges.push_back(e);
}
}
/*!
* Private member function that check if there is already
* an edge between the two vertices
*/
template <class T>
bool Graph::graph<T>::vertex::contains_edge_to_vertex_with_key(const T key)
{
typename std::list<edge>::iterator find_it = m_Edges.begin();
for(; find_it != m_Edges.end(); ++find_it) {
if (find_it->m_Edge->key() == key) {
return true;
}
}
return false;
}
#endif
#ifndef GRAPH_ALGORITHMS_H_
#define GRAPH_ALGORITHMS_H_
#include "graph.h"
namespace Graph
{
template <class T>
class graph_algorithm
{
// Forward declarations of
// internal classes
private :
class vertex_comparer;
public :
graph_algorithm(graph<T> *&graph) :
m_Graph(graph)
{}
// Definition of internal classes
private :
class vertex_comparer
{
public:
bool operator()(graph<T>::vertex &v1, graph<T>::vertex &v2)
{
(t1.key() < t2.key()) ? return true : return false;
}
};
private :
graph<T> *m_Graph;
};
}
#endif
#include "graph_algorithms.h"
#include "graph.h"
#include <cstdlib>
int main(int argc, char *argv[])
{
std::vector<std::pair<int, int> > graph_vect;
for (int i = 0; i < 100; i++) {
graph_vect.push_back(std::pair<int, int>(rand()%20, rand()%20));
}
Graph::graph<int> my_graph(graph_vect);
return 0;
}
通常,如果您在使用模板时看到编译错误,那么最初的几个疑问之一应该是您忘记为依赖类型编写typename
,例如:
bool operator()(graph<T>::vertex &v1, graph<T>::vertex &v2)
应该是这个:
bool operator()(typename graph<T>::vertex &v1, typename graph<T>::vertex &v2)
你看到typename
了吗?同样,您还需要在代码中的任何位置编写typename
- 无论您在哪里使用依赖类型。
如果你想知道什么是依赖类型,放在哪里以及为什么要typename
依赖类型,请阅读以下内容:
- 我必须在哪里以及为什么必须放置"模板"和"类型名称"关键字?
除此之外,您还需要了解private
成员和public
成员之间的区别 - 无论是类型还是变量。在您的情况下,嵌套类型是private
的,我认为应该public
.
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 部分定义/别名模板模板参数
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- #为""定义宏;静态";针对不同的上下文
- 如何确保C++函数在定义之前声明(如override关键字)
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在命名空间中定义函数还是限定函数
- 此代码是否违反一个定义规则
- 编译C++时未定义的引用
- 不同翻译单元中不可重载的非内联函数定义
- 为什么在定义函数之前先声明它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何定义一个纯抽象基类