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

时间:2014-04-09 14:18:20

标签: c++ c++11 variadic-templates

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

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

5 个答案:

答案 0 :(得分:6)

就像那样:

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;

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

以上所有答案都需要深度递归模板即时功能。 请参阅以下资源,无需任何额外的模板即时消息:

#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};
}

答案 3 :(得分: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
};

答案 4 :(得分:0)

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

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

如果索引超出范围

,则在编译时失败