0

是否可以在类型别名中使用模板模板参数?例如,是否可以编写类似于以下的类型别名:

#include "tuple"

template<
    template<class... Types> class Container,
    class... Types
> using another_tuple = std::tuple<Types...>;

another_tuple<std::tuple<int>> t;

哪个,当给定例如 std::tuple 时,将其类型用于其他用途?GCC 和 Clang 在它们的错误中都提到了类模板,我如何避免需要类模板?如果我删除所有 ...s GCC 错误更改为:

error: wrong number of template arguments (1, should be 2)
another_tuple<std::tuple<int>> t;
                            ^

我不明白。容器本身不一定是模板,但我不知道如何使用 std::tuple 代替它。

根据 nms 答案更新,正确格式为:

another_tuple<std::tuple, int> t;

同样,即使类型在容器中:

using types = std::tuple<int, char>;
another_tuple<std::tuple, types> t;

它有一些冗余代码,但应该足够好。

4

1 回答 1

0
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
template<class...>struct types{using type=types;};

template<template<class...>class Z, class types>
struct apply_types;
template<template<class...>class Z, class types>
using apply_types_t=type_t<apply_types<Z,types>>;
template<template<class...>class Z, class...Ts>
struct apply_types<Z,types<Ts...>>:tag<Z<Ts...>> {};

template<template<class...>class M, class types>
struct map;
template<template<class...>class M, class types>
using map_t=type_t<map<M,types>>;
template<template<class...>class M, class...Ts>
struct map<M,types<Ts...>>:types<M<Ts>...>{};

template<class...lists>
struct concat:types<>{};
template<class...lists>
using concat_t=type_t<concat<lists...>>;
template<class...lhs, class...rhs>
struct concat<types<lhs...>,types<rhs...>>:
  types<lhs...,rhs...>
{};
template<class types>
struct concat<types>:
  types
{};
template<class types, class...more_types>
struct concat<types, more_types...>:
  concat<types, concat_t<more_types...>>
{};

template<class A, template<class...>class C, class T, class F>
struct condition:std::conditional<C<A>{}, T, F>{};

template<template<class...>class Z, class... T>
struct bind_1st_n {
  template<class...Ts>
  using apply=Z<T..., Ts...>;
};

template<class Tok, class list, class A>
struct replace_helper:
  condition<A, bind_1st_n<std::is_same, Tok>::template apply, list, types<A>>
{};

template<class list, class if_this, class then_these>
struct replace:
  concat<
    map_t<
      bind_1st_n<replace_helper,if_this, then_these>::template apply,
      list
    >
  >
{};

struct placeholder {};

template<class T> struct get_args;
template<class T> using get_args_t=type_t<get_args<T>>;
template<template<class...>class Z, class...Ts>
struct get_args<Z<Ts...>>:types<Ts...> {};

template<template<class...>class Z, class types>
struct apply;
template<template<class...>class Z, class types>
using apply_t=type_t<apply<Z,types>>;


template< class Container >
using another_tuple = apply_t< std::tuple, get_args_t<Container> >;

如果您希望列表在前面扩展为 int,并在最后加倍:

template< class Container >
using another_tuple = apply_t< std::tuple,
  replace_t<
    types<int, placeholder, double>,
    placeholder,
    get_args_t<Container>
  >
>;

它构建要应用的列表,然后分两步应用它。

此代码均未编译。

于 2015-05-25T20:56:11.713 回答