如何获取整数参数包中的第i个整数

How to get the i-th integer in a integer parameter pack?

本文关键字:整数 包中 参数 获取 何获取      更新时间:2023-10-16

如何获取整数参数包中的第i个整数?例如

template<int... Is>
struct A
{
    enum { CONSTANT_0 = Is[0] }; //Assume the sizeof...(Is) > the index requested
};

类似:

template <size_t I, int N, int... R>
struct pick : pick <I - 1, R...> { };
template <int N, int... R>
struct pick <0, N, R...> : std::integral_constant <int, N> { };

因此

pick <3, 1, 2, 3, 4, 5, 6>::value

等于4,并且

template<int... Is>
struct A
{
    enum { CONSTANT_0 = pick <0, Is...>::value };
};

就是你在你的案例中会如何使用它。


另一种方式:

template <size_t I, int... N>
using pick = typename std::tuple_element <I,
   std::tuple <std::integral_constant <int, N>...>
>::type;

在您的特定示例中,当第一个(或n个第一个)参数被特殊处理时,您可以这样定义模板:

template<int head, int... tail>
struct A {
    enum { CONSTANT_0 = head }; // no need to assume anything about tail...
};

这也让调用者清楚地知道,必须至少有一个参数。

或者您可以尝试这个解决方案,它与之前提出的基本相同,但具有标准功能:

template<int ... Is>
struct A
{
    enum { CONSTANT_0 = std::get<0>(std::make_tuple(std::forward<int>(Is)...)) };
};

如果索引超出范围,则在编译时失败

以上所有答案都需要深度递归模板实例化。参见以下来源,没有任何额外的模板实例化:

#include <iostream>
template< int ... i >
struct A
{
    static constexpr int at_f(int idx)
    {
         using int_list = int[sizeof...(i)];
         return int_list{ i... } [ idx];   
    }
    template< int j>
    struct at 
    {
        enum{ value = at_f(j) };
    };
};

int main()
{
    std::cout << A<0,1,3,4>::at<3>::value << std::endl;
    //or
    int b[ A<0,1,2,3,4>::at_f(2) ]  = {0};
}

使用一些模板元编程:

template<int... INTEGERS>
struct integer_sequence {};
template<typename INDICES , std::size_t INDEX>
struct get;
template<int HEAD , int... TAIL , std::size_t INDEX>
struct get<integer_sequence<HEAD,TAIL...>,INDEX> : public get<integer_sequence<TAIL...>,INDEX-1> {};
template<int HEAD , int... TAIL>
struct get<integer_sequence<HEAD,TAIL...>,0> : public std::integral_constant<int,HEAD>{};

您可以将其用作:

template<int... Is>
struct A
{
    enum { CONSTANT_0 = get<integer_sequence<Is...>,0>::value }; //Assume the sizeof...(Is) > the index requested
};