Можно ли определить unordered_map с вектором <T>в качестве значения? - PullRequest
1 голос
/ 14 января 2020

У меня есть шаблон векторов с их геттерами:

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

Меня интересует какая-то функция типа vector<T>& getByName(string s) const, чтобы я мог вызывать функцию следующим образом: getByName("A"), getByName("B") и т. Д.

Я пытался использовать неупорядоченную карту, но я не нашел подходящего способа создать линию, подобную этой: unordered_map< string, vector<T> >.

A, B, C ... - это совершенно разные структуры, поэтому решение полиморфизма c - это не то, что я ищу, насколько это возможно.

Поскольку vector<T> - это контейнер с фиксированный размер (24 байта, если я не ошибаюсь), я не понимаю, почему карта не может хранить эти байты где-то в памяти независимо от типа вектора.

Ответы [ 2 ]

5 голосов
/ 14 января 2020

Поскольку вектор - это контейнер с фиксированным размером (24 байта, если я не ошибаюсь), я не понимаю, почему карта не может хранить эти байты где-то в памяти независимо от типа вектора.

Поскольку C ++ является строго типизированным языком, и тот факт, что типы vector<A>, vector<B> и vector<C> имеют одинаковый размер , не имеет значения, поскольку они разные типы .

A pair<int16_t, int16_t> имеет тот же размер, что и int32_t (в большинстве реализаций), но это не делает их взаимозаменяемыми.

Вы можете (я полагаю) иметь map<string, variant<...> или map<string, any>, но это потребует от вас управления всеми типами самостоятельно.

[Позже]

Меня интересует какая-то функция вроде vector<T>& getByName(string s)

Проблема с такой функцией заключается в том, что вам придется указывать (во время компиляции) тип, который будет возвращать функция. Вы хотели бы, чтобы тип возвращаемого значения определялся значением параметра, передаваемого функции во время выполнения.

1 голос
/ 14 января 2020

Вы не можете иметь vector<A>, vector<B>, .. в одном 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;
}
...