由于 unordered_map 与 struct 作为键一起使用,显式默认的默认构造函数被隐式删除
Posted
技术标签:
【中文标题】由于 unordered_map 与 struct 作为键一起使用,显式默认的默认构造函数被隐式删除【英文标题】:Explicitly defaulted default constructor is implicitly deleted because of unordered_map used with a struct as key 【发布时间】:2020-11-04 10:42:39 【问题描述】:我有以下 Graph 类:
class Graph
private:
struct Edge
string vertex1, vertex2;
int val;
Edge() = default;
~Edge() = default;
explicit Edge(string v1, string v2, int value) : vertex1(std::move(v1)), vertex2(std::move(v2)), val(value) ;
bool operator==(const Edge&) const;
;
unordered_map<Edge, Edge*> edges;
public:
Graph() = default;
~Graph();
当我想用默认构造函数构造一个 Graph 时,它会显示Explicitly defaulted default constructor of 'Graph' is implicitly deleted because field 'edges' has a deleted default constructor
。我应该如何更改我的代码,以便能够使用 Graph 的默认构造函数?
【问题讨论】:
【参考方案1】:unordered_map
中的 Key 需要是可散列的。通过添加 std::hash
类模板的特化或在创建 unordered_map
时提供散列函子。
您还没有证明您已经进行了 std::hash<Edge>
特化,并且您没有使用仿函数创建 unordered_map
来进行散列,这就是默认构造失败的原因。
要添加std::hash<Edge>
专业化,您可以这样做(如果您将Edge
公开):
namespace std
template<>
struct hash<Graph::Edge>
size_t operator()(const Graph::Edge& e) const
size_t hash_result;
// calculate the hash result
return hash_result;
;
// namespace std
如果您想保留Edge
private
,使用仿函数可能更容易。这是struct
形式的示例,它使unordered_map
默认可构造:
class Graph
private:
struct Edge
// ...
;
// the hashing functor:
struct edge_hasher
size_t operator()(const Edge& e) const
// an example implementation using boost::hash_combine
// from <boost/container_hash/hash.hpp>:
std::hash<std::string> h;
size_t hash_result = 0;
boost::hash_combine(hash_result, h(e.vertex1));
boost::hash_combine(hash_result, h(e.vertex2));
boost::hash_combine(hash_result, std::hash<int>(e.val));
return hash_result;
;
std::unordered_map<Edge, Edge*, edge_hasher> edges; // <- hasher included
public:
Graph() = default;
~Graph();
【讨论】:
以上是关于由于 unordered_map 与 struct 作为键一起使用,显式默认的默认构造函数被隐式删除的主要内容,如果未能解决你的问题,请参考以下文章