【问题标题】:Explicitly defaulted default constructor is implicitly deleted because of unordered_map used with a struct as key由于 unordered_map 与 struct 作为键一起使用,显式默认的默认构造函数被隐式删除
【发布时间】: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 的默认构造函数?

【问题讨论】:

    标签: c++ unordered-map default-constructor


    【解决方案1】:

    unordered_map 中的 Key 需要是可散列的。通过添加 std::hash 类模板的特化或在创建 unordered_map 时提供散列函子。

    您还没有证明您已经进行了 std::hash&lt;Edge&gt; 特化,并且您没有使用仿函数创建 unordered_map 来进行散列,这就是默认构造失败的原因。

    要添加std::hash&lt;Edge&gt; 专业化,您可以这样做(如果您将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();
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多