Как распаковать std :: tuple из шаблона C ++? - PullRequest
6 голосов
/ 17 апреля 2020

У меня есть класс, который, как ожидается, будет принимать std::tuple определенных типов (допускается произвольное количество) в качестве аргумента шаблона. Я хочу объявить кортеж векторов типов. Например, у меня есть

template <typename T>
class MyClass {/*...*/}

Я создаю его экземпляр

MyClass<std::tuple<int, bool>> my_class;

, и я стремлюсь создать поле, подобное этому

std::tuple<std::vector<int>, std::vector<bool>> my_tuple;

Я знаю, что если бы я имел определение класса

template <typename... T>
class MyClass2 {/*...*/}

Я мог бы создать его экземпляр, передав типы данных без кортежа

MyClass<int, bool> my_class2;

, а затем просто создать поле

std::tuple<std::vector<int>, std::vector<bool>> my_tuple2;

, используя

std::tuple<std::vector<T>...> my_tuple2;

Поэтому я подумал, что мне следует каким-то образом распаковать типы данных из кортежа. Возможно ли это?

Ответы [ 2 ]

3 голосов
/ 17 апреля 2020

Да, и чтобы добавить к ответу cigien, еще один способ go об этом - распаковать его через специализацию шаблона.

template<typename Tuple>
class MyClass;

template<typename... Ts>
class MyClass<std::tuple<Ts...>>
{
    // ...
    using VectorTuple = std::tuple<std::vector<Ts>...>;
    // ...
};
3 голосов
/ 17 апреля 2020

Конечно, вам просто нужен еще один уровень косвенности (как обычно):

// this function declaration is used just for the type
// transformation, and needs no definition
template <typename... Types>
auto unpack(std::tuple<Types...>) -> std::tuple<std::vector<Types>...> ;

template <typename Tuple>
class MyClass
{
  // use the return type of unpack
  decltype(unpack(std::declval<Tuple>())) my_tuple; 
};

И теперь вы можете создать экземпляр MyClass с tuple, например:

MyClass<std::tuple<int, double>> m;

, который содержит поле my_tuple типа

std::tuple<std::vector<int>, std::vector<double>>

Вот рабочая демоверсия .

...