【问题标题】:How to access template template parameters in type alias?如何访问类型别名中的模板模板参数?
【发布时间】:2015-08-07 05:05:27
【问题描述】:

是否可以在类型别名中使用模板模板参数?例如是否可以写一个类似这样的类型别名:

#include "tuple"

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

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

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

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

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

根据n.m.s的回答更新,正确的格式是:

another_tuple<std::tuple, int> t;

即使类型在容器中也是如此:

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

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

【问题讨论】:

标签: c++11 template-templates type-alias


【解决方案1】:
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>
  >
>;

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

此代码均未编译。

【讨论】:

    猜你喜欢
    • 2014-01-29
    • 2018-08-26
    • 2023-01-25
    • 2021-11-21
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多