C++ 除了最后一个模板参数外,是否有任何方法可以访问所有内容?

C++ 除了最后一个模板参数外,是否有任何方法可以访问所有内容?,c++,c++11,C++,C++11,可以按如下方式使用模板参数包: template <int T1, int... Ts> struct Test { static constexpr int sizes[] = {Ts...}; }; template <int T1, int... Ts> constexpr int Test<T1, Ts...>::sizes[]; Foo<Ts...> foo; 访问最后一个模板参数的最有效方法是什么 您可以使用一个小助手将参

可以按如下方式使用模板参数包:

template <int T1, int... Ts>
struct Test {
  static constexpr int sizes[] = {Ts...};
};

template <int T1, int... Ts>
constexpr int Test<T1, Ts...>::sizes[];
  Foo<Ts...> foo;
访问最后一个模板参数的最有效方法是什么

您可以使用一个小助手将参数包转换为数组

template<int... Args>
struct pack {
    static constexpr std::array as_array{ Args... };
};
模板
结构包{
静态constexpr std::array as_array{Args…};
};
然后可以使用数组索引获取最后一个参数:

template <int T1, int... Ts>
struct Test {
    static constexpr int last = pack<Ts...>::as_array[sizeof...(Ts) - 1];
模板
结构测试{
static constexpr int last=pack::as_数组[sizeof…(Ts)-1];
是一种方法:

template <typename SeqN, typename Seq> struct TestImpl;

template <int... Ns, std::size_t ... Is>
struct TestImpl<std::integer_sequence<int, Ns...>, std::index_sequence<Is...>>
{
private:
    using SeqTuple = std::tuple<std::integral_constant<int, Ns>...>;
public:
  static constexpr int sizes[] = {std::tuple_element_t<Is, SeqTuple>::value...}; 
  Foo<std::tuple_element_t<Is, SeqTuple>::value...> foo;
};


template <int N1, int N2, int... Ns> // At least 2 numbers
using Test = TestImpl<std::integer_sequence<int, N1, N2, Ns...>,
                      std::make_index_sequence<1 + sizeof...(Ns)>>;
模板结构TestImpl;
模板
结构测试
{
私人:
使用SeqTuple=std::tuple;
公众:
静态constexpr int size[]={std::tuple\u element\u t::value…};
富富,;
};
模板//至少2个数字
使用Test=TestImpl;

您可以使用标准方法使用
std::index\u序列

template<template<auto...> typename Tmp, size_t... Is, typename... Args>
constexpr auto take_as(std::index_sequence<Is...>, Args...)
{
    using Tup = std::tuple<Args...>;
    return Tmp<std::tuple_element_t<Is, Tup>{}...>{};
}

template<auto... Vals>
struct except_last
{
    template<template<auto...> typename Tmp>
    using as = decltype(take_as<Tmp>(std::make_index_sequence<sizeof...(Vals) - 1>{},
                                     std::integral_constant<decltype(Vals), Vals>{}...));
};
模板
constexpr自动取为(std::index_序列,Args…)
{
使用Tup=std::tuple;
返回Tmp{};
}
模板
除最后一个外的结构
{
模板
使用as=decltype(take_as(std::make_index_sequence{},
std::积分常数{}…);
};
你用它作为

using F = except_last<1, 2, 3, 4>::as<Foo>;  // F is Foo<1, 2, 3>
使用F=except\u last::as;//F是Foo
这很容易实现和阅读,但你可能会得到O(n)实例化深度。如果你沉迷于效率,你可以通过滥用折叠表达式来实现O(1)实例化深度

template<typename T>
struct tag
{
    using type = T;
};

template<typename F, typename... Ts>
using fold_t = decltype((F{} + ... + tag<Ts>{}));

template<size_t N, typename... Ts>
struct take
{    
    template<typename T>
    auto operator+(tag<T>) -> take<N - 1, Ts..., T>;
};

template<typename... Ts>
struct take<0, Ts...>
{
    template<template<auto...> typename Tmp>
    using as = Tmp<Ts{}...>;

    template<typename T>
    auto operator+(tag<T>) -> take<0, Ts...>;
};

template<auto... Vals>
struct except_last
{
    template<template<auto...> typename Tmp>
    using as = fold_t<take<sizeof...(Vals) - 1>,
                      std::integral_constant<decltype(Vals), Vals>...>::template as<Tmp>;
};
模板
结构标签
{
使用类型=T;
};
模板
使用fold_t=decltype((F{}+…+标记{}));
模板
构造带
{    
模板
自动操作员+(标签)->获取;
};
模板
构造带
{
模板
使用as=Tmp;
模板
自动操作员+(标签)->获取;
};
模板
除最后一个外的结构
{
模板
使用as=fold\u t::template as;
};

Brilliant。除了最后一个参数之外,我可以获取所有内容吗?@MTMD您可以使用索引通过数组访问所有元素。但是如果您想要一个包含除最后一个元素之外的所有内容的参数包,那么这种方法可能并不理想。这正是我想要的(称为
Foo
)。你能提出一些建议吗?@MTMD我认为递归模板可以工作,就像它可以用于几乎所有与参数包相关的东西一样,但可能有更好的方法。如果采用该标准,这将变得微不足道:)正是:)。谢谢。我想我会使用递归模板。你的确切意思是什么这里是“高效的”?最少的代码量?最快的编译速度?还有别的吗?@MichaelKenzel。代码量并不重要。我非常希望它是编译时可计算的。
std::get(SeqTuple{})::value
(添加大括号)?@Quentin:的确,排印错误已修复(另一种方式)你不能用
std::forward(Vals)
std::forward(Vals)作为元组(Vals)
?@Caleth替换
std::integral_常量…
。@Caleth关键是在类型中嵌入值,所以不能。嵌入的原因是转发“constexpr”“在调用堆栈中,我们不能将
constexpr
参数作为值。
template<typename T>
struct tag
{
    using type = T;
};

template<typename F, typename... Ts>
using fold_t = decltype((F{} + ... + tag<Ts>{}));

template<size_t N, typename... Ts>
struct take
{    
    template<typename T>
    auto operator+(tag<T>) -> take<N - 1, Ts..., T>;
};

template<typename... Ts>
struct take<0, Ts...>
{
    template<template<auto...> typename Tmp>
    using as = Tmp<Ts{}...>;

    template<typename T>
    auto operator+(tag<T>) -> take<0, Ts...>;
};

template<auto... Vals>
struct except_last
{
    template<template<auto...> typename Tmp>
    using as = fold_t<take<sizeof...(Vals) - 1>,
                      std::integral_constant<decltype(Vals), Vals>...>::template as<Tmp>;
};