2014-04-09 42 views

回答

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; 
+0

谢谢。只是觉得奇怪为什么编译器不直接支持通用要求。 – user1899020

+2

@ user1899020这是一个很好的问题。就像*为什么我必须使用索引技巧来提取元组元素并将它们传递给可变参数函数? – Manu343726

+1

@ user1899020使用'std :: tuple_element'增加了另一种方式。我也觉得这应该是编译器的一个任务,比如'sizeof ...()'。 – iavr

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

在你的具体例子,在处理第一个(或第一个)参数特别是,你可以像这样定义模板:

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

这也明确了调用者必须至少有一个参数。

0

或者你可以尝试这种解决方案,这基本上与先前提出,但与标准功能:

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

在编译时失败,如果该指数超出范围

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