У меня есть 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</*???*/>;
Возможно ли что-то подобное? Может быть, короткое решение?
Небольшая частичная специализация с использованием параметров шаблона шаблона должна сделать эту работу (обобщенную для шаблонов с переменными параметрами, а не только для кортежей):
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).
Вы могли бы объявить структуру update_tuple
с двумя параметрами шаблона:
T
— будет шаблонным, и этот параметр мы будем применять к параметрам в tuple
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
может принять более одного параметра шаблона (когда другие, но сначала имеют значения по умолчанию).