【问题标题】:Is it possible to define an unordered_map with a vector<T> as value?是否可以使用 vector<T> 作为值来定义 unordered_map?
【发布时间】:2020-04-30 18:33:38
【问题描述】:

我有一个带有 getter 的向量模式,如下所示:

vector<A>& getA() const { return a; }
vector<B>& getB() const { return b; }
vector<C>& getC() const { return c; }
...

我很想拥有像vector&lt;T&gt;&amp; getByName(string s) const 这样的函数,这样我就可以这样调用函数:getByName("A"),getByName("B") 等等。

我尝试过使用无序地图,但没有找到任何合适的方法来制作这样的线条:unordered_map&lt; string, vector&lt;T&gt; &gt;

A、B、C...是完全不同的结构体,所以我尽可能不寻找多态解决方案。

由于vector&lt;T&gt; 是一个固定大小的容器(如果我没记错的话,是 24 个字节),我不明白为什么无论向量的类型如何,地图都无法将这些字节存储在内存中的某个位置。

【问题讨论】:

  • 如果 A BC 都是不同的类型,那么这是不可能的,因为最大的问题是你不能声明 std::vector&lt;T&gt; 来保存不同的非多态类型
  • 你可以有一个模板函数get_vector&lt;T&gt;(),它会返回一个vector&lt;T&gt;。但是,T 必须在编译时指定,因此如果这是您的想法,它将不适用于运行时值。

标签: c++ templates vector stl unordered-map


【解决方案1】:

由于向量是一个具有固定大小的容器(如果我没记错的话是 24 个字节),我不明白为什么无论向量的类型如何,地图都无法将这些字节存储在内存中的某个位置。

因为 C++ 是一种强类型语言,vector&lt;A&gt;vector&lt;B&gt;vector&lt;C&gt; 类型相同这一事实并不重要,因为它们是不同的 类型

pair&lt;int16_t, int16_t&gt;int32_t 大小相同(在大多数实现中),但这并不意味着它们可以互换。

您可以(我想)拥有map&lt;string, variant&lt;...&gt;map&lt;string, any&gt;,但这需要您自己管理所有类型。

[稍后]

我有兴趣拥有某种功能,例如vector&lt;T&gt;&amp; getByName(string s)

这样一个函数的问题是你必须(在编译时)指定一个函数返回的类型。您希望返回类型由运行时传递给函数的参数值确定。

【讨论】:

  • 感谢您的解释。我不知道变体/任何内容,经过仔细阅读,这正是我在这个问题上所需要的。我很感激
【解决方案2】:

您不能将vector&lt;A&gt;vector&lt;B&gt;、.. 放在一个unordered_map 中,因为它们有不同的类型。我认为以下解决方案最符合您的需求:

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

using namespace std;

template<typename T>
class my_unordered_map :
        public unordered_map<string, vector<T>> {
};

template<typename T>
vector<T>& get_by_name(const string& s, my_unordered_map<T>& mm) {
    return mm[s];
}

class A {
public:
    string name;

    A() = default;

    explicit A(const string& s) : name{s} {}
};

int main() {
    vector<A> vec_a1{A{"A1"}};

    my_unordered_map<A> mm;
    mm["A"] = vec_a1;

    vector<A>& vec_a2 = get_by_name("A", mm); //vec_a2 is the same as mm["A"]
    vec_a2.emplace_back("B");

    for (const auto& item : vec_a2) {
        cout << item.name << "\n";
    }

    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 2013-05-31
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 2015-12-16
    • 1970-01-01
    • 2020-07-18
    相关资源
    最近更新 更多