如何将 std::unordered_map 部分专门化为我的模板类的成员?

Posted

技术标签:

【中文标题】如何将 std::unordered_map 部分专门化为我的模板类的成员?【英文标题】:How to partially specialize std::unordered_map as a member of my templated class? 【发布时间】:2021-06-20 01:20:22 【问题描述】:

我似乎无法理解为什么这不起作用:

#include <unordered_map>
#include <vector>

template<typename T>
struct Bar 
    Bar(const T &t) : xt 
    T x;
;

template<typename T>
struct Foo 
    std::unordered_map<T, Bar<T>> u;

    Foo(const std::vector<T> &v) 
        for (const T &i : v)
            u[i] = Bar(i);
        
;

int main() 
    Foo<int> f(1, 2, 3);

Try it here

我想要的是有一个 Foo 的实例,它包含一个 unordered_map,它将 T 类型的对象映射到 Bar 类型的对象。不幸的是,错误消息没有我希望的那么有用: error: no matching function for call to 'Bar&lt;int&gt;::Bar()'

这里发生了什么?我该如何解决这个问题?

【问题讨论】:

std::map::operator[] 要求 value_typeDefaultConstructible,而 Bar&lt;T&gt; 不是。 @songyuanyao 谢谢,就是这样。使用std::unordered_map::insert 解决了这个问题。我只希望错误消息能更有帮助。尽管它确实告诉我它想要默认构造函数(或者更确切地说是一个没有参数的构造函数),但我希望它会告诉我它想要因为 operator[] 【参考方案1】:

正如@songyuanyao 非常聪明地注意到的那样,问题在于std::unordered_map::operator[] 返回了对映射类型的引用,这需要一个不带参数的构造函数。使用std::unordered_map::insert 解决了这个问题,不需要在bar 中引入这样的构造函数:

#include <unordered_map>
#include <vector>

template<typename T>
struct Bar 
    Bar(const T &t) : xt 
    T x;
;

template<typename T>
struct Foo 
    std::unordered_map<T, Bar<T>> u;

    Foo(const std::vector<T> &v) 
        for (const T &i : v)
            u.insert(i, Bar<T>(i));
        
;

int main() 
    Foo<int> f(1, 2, 3);

Try it here

【讨论】:

以上是关于如何将 std::unordered_map 部分专门化为我的模板类的成员?的主要内容,如果未能解决你的问题,请参考以下文章

如何同时填充 std::unordered_map ?

如何以线程安全的方式使用`std::unordered_map`?

std::unordered_map 如何表现? [C++]

C++ 将预先保留的哈希映射(std::unordered_map)与整数键和连续数据数组(std::vector)进行比较

如何在删除元素时防止重新散列 std::unordered_map?

CDT 索引器找不到 std::unordered_map