C ++ Таблица векторов разных типов - PullRequest
1 голос
/ 11 июня 2019

У меня есть коллекция векторов разных типов, таких как:

std::vector<int> a_values;
std::vector<float> b_values;
std::vector<std::string> c_values;

Каждый раз, когда я получаю новое значение для a, b и c, я хочу передать их в соответствующие векторы a_values, b_values и c_values.

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

Первый ответ на этот пост https://softwareengineering.stackexchange.com/questions/311415/designing-an-in-memory-table-in-c кажется уместным, но я хочу легко получить вектор для заданного имени, без необходимости вручную приводить к определенному типу. то есть. Я хочу позвонить getValues("d"), который даст мне базовый std::vector.

У кого-нибудь есть базовый пример класса коллекции, который делает это?

1 Ответ

1 голос
/ 12 июня 2019

Эта идея может быть реализована с помощью гетерогенного контейнера tuple, который позволит хранить векторы, содержащие элементы различных типов.

В частности, мы можем определить простую структуру данных следующим образом

template <typename ...Ts>
using vector_tuple = std::tuple<std::vector<Ts>...>;

В начальном случае из представленного примера три вектора a_values, b_values, c_values просто соответствуют типу vector_tuple<int, float, std::string>.Добавление дополнительного вектора просто требует добавления дополнительного типа в нашу коллекцию.

Индексация в нашей новой коллекции также проста, учитывая коллекцию

vector_tuple<int, float, std::string> my_vec_tup;

, у нас есть следующие методы для извлечения a_values:b_values ​​и c_values ​​

auto const &a_values = std::get<0>(my_vec_tup);

auto const &b_values = std::get<1>(my_vec_tup);

auto const &c_values = std::get<2>(my_vec_tup);

Обратите внимание, что контейнер tuple индексируется во время компиляции, что отлично, если вы знаете предполагаемый размер во время компиляции, но в противном случае будет неподходящим.

В приведенном описании проблемы число векторов, по-видимому, решается во время компиляции, а соглашение об именовании кажется произвольным и постоянным (т. Е. Индекс выигранных векторов 'должны быть изменены во время выполнения).Следовательно, кортеж векторов представляется подходящим решением, если вы связываете каждое имя с целочисленным индексом.

Что касается второй части вопроса (т. Е. Итерации по каждому вектору), если выс помощью C ++ 17 хорошая новость заключается в том, что вы можете просто использовать функцию std::apply, чтобы сделать это: https://en.cppreference.com/w/cpp/utility/apply Все, что требуется, - это передать функцию, которая принимает вектор (вы можете определить соответствующиеперегрузка для обработки каждого контейнера отдельно), и ваш кортеж к std::apply.

Однако для более ранних версий C ++ вам нужно будет реализовать собственную функцию for_each.К счастью, эта проблема уже решена: Как перебрать элементы std :: tuple?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...