我正在尝试为学习目的实现各种数据结构和算法。
目前我正在尝试实现Graph类模板,但我在尝试使用STL unordered_map
(以及将来consequently priority_queue
时遇到问题)。
基本上,由于某种原因,当尝试初始化图形中的顶点地图时,模板类型不匹配。根据我的理解,因为我只计划使用本机C ++类型的键类型,只要我的值类型是指针,除了我的自定义顶点类的复制构造函数之外,我不需要做任何额外的工作。默认的比较器/ hasher应该足够了。但它没有,我收到的错误有点难以理解。
错误:
Error 1 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::unordered_map<T,graph<T>::vertex *,std::hash<int>,std::equal_to<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' (or there is no acceptable conversion)
代码:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <unordered_map>
#include <numeric>
#include <functional>
using namespace std;
class vertex;
template <class T>
class graph {
public:
graph() { verts = unordered_map<T, vertex*>(); }
~graph() {
for each(auto v in verts)
delete(v);
delete(verts);
}
private:
unordered_map<T, vertex*> verts;
// --- Inner Classes ---
struct path {
vertex *dest;
double cost;
path(vertex *d = nullptr, double c = 0.0) : dest(d) : cost(c) {}
inline int compare(const path& p) {
auto other = p.cost;
return cost < other ? -1 :
cost > other ? 1 : 0;
}
};
struct edge {
vertex *dest;
double cost;
edge(vertex *d = nullptr, double c = 0.0) : dest(d) : cost(c) {}
};
class vertex {
public:
// Vertex relationships
T name;
vector<edge>* adj;
// Path Finding Information
double distance;
vertex *prev;
int scratch;
void reset_path_finding() {
distance = double.infinity();
prev = nullptr;
scratch = 0;
}
vertex(T name = default(T)) : name(name) : adj(new vector<edge>) :
distance(double.infinity()) : prev(nullptr) : scratch(0) {}
vertex(const vertex& v) {
name = v.name;
adj = v.adj;
distance = v.distance;
prev = v.prev;
scratch = v.scratch;
}
~vertex() { delete(adj); }
private:
};
};
int main()
{
graph<int> myGraph = graph<int>();
cout << "Press any key to continue..." << endl;
int x;
cin >> x;
return 0;
}
答案 0 :(得分:3)
第一个问题是在声明之前使用嵌套类graph::vertex
。由于您已在{/ 1>} class vertex
之外声明graph
,因此导致进一步混淆,因此编译器最初认为您的意思是该类。您可以在vertex
:
graph
template <class T>
class graph {
class vertex;
private:
// and so on
};
还有其他一些语法错误,如果您查看错误消息引用的行,这些错误应该很明显。基于范围的for循环的语法是
for (auto v : verts) // not for each(auto v in verts)
这为您提供了键值对,因此要删除vertex
,您需要
delete v.second;
更好的是,将verts
更改为unordered_map<T, vertex>
,包含对象而不是指针,它将自动管理所有内存 - 根本不需要析构函数。
值初始化临时的语法是
T() // not default(T)
构造函数的初始化列表中的子句用逗号分隔,而不是冒号:
path(vertex *d = nullptr, double c = 0.0) : dest(d) , cost(c) {}
^ not :
具有无限值的double
是
std::numeric_limits<double>::infinity() // not double.infinity()
您需要加入<limits>
。
verts
不需要在析构函数中删除,因为你没有new
它。它也不需要在构造函数中从默认构造的临时赋值中分配,因为它只是默认构造的。
有些地方你通过不必要地使用指针和new
让自己变得困难。除非你确实需要,否则尽量避免使用new
;并了解RAII,尤其是智能指针和容器的使用。