извлечь класс из кортежа

У меня есть std :: tuple, как это:

typedef std::tuple<t1, t2, t3> tuple_t;

Теперь я хочу преобразовать t3_tuple в похожий кортеж:

typedef std::tuple< T<t1>, T<t2>, T<t3> > derived_tuple_t;

В моем случае, например, t1, t2, а также t3 примитивы, и T является std::stack, В общем, предположим, что это может быть t4 и так далее.

Конечно, мое второе определение уже решает проблему, но я бы хотел, чтобы вывод был автоматическим: только учитывая T а также tuple_tПострой меня derived_tuple_t, Как это:

template <class T, class tuple_t> using derived_tuple_t = std::tuple</*???*/>;

Возможно ли что-то подобное? Может быть, короткое решение?

3

Решение

Небольшая частичная специализация с использованием параметров шаблона шаблона должна сделать эту работу (обобщенную для шаблонов с переменными параметрами, а не только для кортежей):

template<template<class...> class TT, class ArgsT>
struct make_over;

template<template<class...> class TT, template<class...> class ArgsT, class... Ts>
struct make_over<TT, ArgsT<Ts...>>{ using type = ArgsT<TT<Ts>...>; };

template<template<class...> class TT, class ArgsT>
using MakeOver = typename make_over<TT, ArgsT>::type;

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

Живой пример.

3

Другие решения

Вы могли бы объявить структуру update_tuple с двумя параметрами шаблона:

  1. T — будет шаблонным, и этот параметр мы будем применять к параметрам в tuple
  2. std::tuple с переменным количеством параметров шаблона.

Затем просто создайте псевдоним для нового tuple с аргументами, примененными с T используя расширение пакета

#include <tuple>
#include <type_traits>
#include <vector>

template <template<class...> class, class>
struct update_tuple;

template <template <class...> class T, class... Args>
struct update_tuple<T, std::tuple<Args...>>
{
using type = std::tuple<T<Args>...>;
};

int main()
{
static_assert
(
std::is_same
<
std::tuple<std::vector<int>, std::vector<double>>,
update_tuple<std::vector, std::tuple<int, double>>::type
>::value,
"They are not same");
return 0;
}

Благодаря @Xeo: код не потерпит неудачу, если T может принять более одного параметра шаблона (когда другие, но сначала имеют значения по умолчанию).

пример

4

По вопросам рекламы [email protected]