在折叠表达式中减少模板参数

4

考虑下面的代码:

template<typename...>
struct C
{ /* ... */ };

template<typename T, unsigned N>
struct B
{
    using type = /* ... */;
};

template<size_t N, typename... Ts>
struct A
{
    using type = C<typename B<Ts, N-->::type...>; // decrement N sizeof...(Ts) times
};

因此举个例子:

typename A<5, int, long, void>::type

扩展到

C<typename B<int, 5>::type, typename B<long, 4>::type, typename B<void, 3>::type>

由于N是一个const值,所以此代码无法编译。有其他的方法吗?


这是一个常量表达式。这就像尝试执行5--一样,毫无意义。 - Nicol Bolas
1
你想要做什么?你需要解决的实际问题是什么(如果有的话)?为什么你需要减少这个值? - Some programmer dude
1
顺便提一下,这不是折叠表达式。 - Evg
听起来你想要一个反向整数序列 - NathanOliver
2
N-1 有什么问题吗? - 463035818_is_not_a_number
显示剩余6条评论
2个回答

9
N 中减去一个 std::index_sequence
namespace detail {
    template<size_t N, typename... Ts, size_t... Is>
    C<typename B<Ts, N - Is>::type...> A_impl(std::index_sequence<Is...>);
}

template<size_t N, typename... Ts>
struct A
{
    using type = decltype(detail::A_impl<N, Ts...>(std::index_sequence_for<Ts...>{}));
};

1
看起来很完美。 - Evg
哇,这与我想出来的非常相似,甚至对于非类型模板 size_t... 的模板参数名称也一样。 - AndyG

2

您可以使用一个未定义或调用的模板static constexpr辅助函数来实现:

template<size_t N, typename... Ts>
struct A
{
    template<size_t... Is>
    static constexpr auto type_getter(std::index_sequence<Is...>) -> C<typename B<Ts, N-Is>::type...>;
    using type = decltype(type_getter(std::index_sequence_for<Ts...>{}));
};

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接