STL 映射自定义键类 [默认构造函数]
STL map Custom Key Class [default constructor]
>我有一个带有 Node 类的图形实现,如下所示
class Node {
public:
Node() : idx(0), volume(1.0), futureVol(1.0), isCoarse(false) { }
Node(index n) : idx(n), volume(1.0), futureVol(1.0), isCoarse(false) { }
Node(const Node& a) : idx(a.idx), volume(a.volume), futureVol(a.futureVol), isCoarse(a.isCoarse) { }
...
bool operator<(const Node& n) const {
return futureVol > n.futureVol;
}
bool operator==(const Node& n) const {
return idx > n.idx;
}
Node& operator=(const Node& node){
if(this != &node){
futureVol = node.futureVol;
volume = node.volume;
isCoarse = node.isCoarse;
idx = node.idx;
}
return *this;
}
private:
index idx;
double volume;
double futureVol;
bool isCoarse;
};
以及具有以下实现的图形:
class Graph{
private:
std::map<Node,std::vector<Node>> edges;
std::map<index, std::map<index, edgeweight>> edgeWeights;
std::map<index, Node> nodes;
Graph(const Graph& g);
Graph& operator=(const Graph& g);
count numNodes;
public:
Graph(count& n); //default
~Graph(); //destructor
Graph(std::vector<Node>&);
void print();
const std::vector<Node> neighbors(const index& idx) const;
const std::vector<Node> coarseNeighbors(const index& idx) const;
void addEdge(index &node1, index &node2, edgeweight& weight);
void addEdges(std::map<index, std::map<index, edgeweight> >& e );
edgeweight weight(const index& idx, const index& idx2) const;
edgeweight weightedDegree(const index& idx) const;
count degree(const index& idx) const;
std::map<index, Node>& getNodes(){return nodes;}
const count getSize() const { return numNodes; }
};
#endif
和图表.cpp:
#include "graph.h"
#include <algorithm>
Graph::Graph(count& n):
edges(),
edgeWeights(),
nodes(),
numNodes(n)
{
for(index i=0; i<numNodes;i++){
Node n(i);
nodes[i] = n;
}
}
...
void Graph::addEdge(index& n1, index& n2, edgeweight& weight){
edgeWeights[n1][n2]= weight;
edgeWeights[n2][n1]= weight;
edges[nodes[n1]].push_back(nodes[n2]);
edges[nodes[n2]].push_back(nodes[n1]);
}
...
问题是每当我添加新边缘时。调用 Node 的默认构造函数,我最终将 0 作为节点 Id,而不是传递给addEdge
的原始节点,例如addEdge(1,2,4.0)
会将边缘 0 <--> 2 添加到图形中。任何帮助将不胜感激。
我尝试编写如下自定义哈希函数,但没有帮助:
namespace std
{
template <>
struct hash<Node>
{
size_t operator()(const Node& n) const
{
return (hash<float>()(n._index()) >> 1);
}
};
}
回想一下,std::map
使用operator<
,从不operator==
。它认为两个键等效,只要!(key1 < key2) && !(key2 < key1)
.
您的Node::operator<
比较futureVol
,您从未将其设置为默认值 1.0
以外的任何值,因此就std::map<Node, ...>
而言,您的程序创建的所有节点都彼此等效。因此,edges
地图只有一个条目。当你写的时候
edges[nodes[n1]].push_back(nodes[n2]);
edges[nodes[n2]].push_back(nodes[n1]);
这两个语句更新同一条目。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数