2012-10-03 5 views
2

주형으로서 정의 피보나치 수 :가변 범위 템플릿을 사용하여 시퀀스 범위를 펼치십시오.

template <unsigned int N> struct Fibonacci { unsigned int value = /*...*/; }; 

무엇 I 필요한 것은이 시퀀스의 첫 번째 N 요소 constexpr 어레이를 얻는 것이다. 나는 가변 인자 템플릿을 사용하여, 그것을 할 수 있습니다 : 그것은 인덱스를 수동으로 열거를 피하고, 필요한 값의 단지 수와 같은 배열을 얻기 위해 가능한

template <unsigned int ... Numbers> 
struct FibArray 
{ 
    static constexpr array<unsigned int, sizeof...(Numbers)> value = { Fibonacci<Numbers>::value... }; 
}; 
// and then: 
const auto fib_array = FibArray<1, 2, 3, 4, 5, 6, 7>::value; 

인가? 이런 식으로 뭔가 : 당신은 인덱스를 생성하여이 동작을 얻을 수 있습니다

const array<unsigned, 7> fib_array = GetFirstNFibValues<7>::value; 

답변

5

:

template<unsigned...> struct indices{}; 

template<unsigned N, unsigned... Indices> 
struct indices_gen : indices_gen<N-1, N-1, Indices...>{}; 

template<unsigned... Indices> 
struct indices_gen<1, Indices...>{ 
    using type = indices<1, Indices...>; 
}; 

#include <array> 

template<unsigned N> 
struct fibonacci{ 
    static constexpr unsigned value = N; // yes, lazyness on my part 
}; 

template<class IPack> 
struct first_n_fib_impl; 

template<unsigned... Is> 
struct first_n_fib_impl<indices<Is...>> 
{ 
    using arr_type = std::array<unsigned, sizeof...(Is)>; 
    static constexpr arr_type value = {{ fibonacci<Is>::value... }}; 
}; 

template<unsigned... Is> 
constexpr std::array<unsigned, sizeof...(Is)> first_n_fib_impl<indices<Is...>>::value; 

template<unsigned N> 
struct first_n_fib 
    : first_n_fib_impl<typename indices_gen<N>::type> 
{ 
}; 

Live example (to show that [1..7] is indeed generated).

+0

나는 아직도 내가 나중에 내 피드백을 게시합니다, 솔루션을 읽고, 그렇게 해요, 하지만 당신에 대해 마지막으로 알아 차림으로 - 실제로 정적 인 constexpr 배열을 g ++ - 4.7.1의 클래스 안에 포함 할 수 있습니다 (그러나 icc에서는 사용할 수 없습니다). gcc에서 비표준 확장인지 아니면 불완전한 constexpr 구현인지 (intex 문서에서는 constexpr 기능이 13.0에서는 불완전하지만 생략 된 것은 말하지 않음) – Vasily

+0

@Vasily : I 실제로'static constexpr' 배열을 GCC 4.7.2 (LWS에서 내 대답에 링크되어 있음)로 시도해 보았지만 해결되지 않은 외부 기호에 대해 불평하지만 어쩌면 그것은 원거리 루프에서 참조를 사용했기 때문일 수 있습니다. .. 흠. – Xeo

+0

예. 나는 그것을 참조. 예를 들어이 배열을 사용하여 배열 크기 'int arr [Struct :: stat_arr [2]];를 정의 할 수는 있지만 모든 for 루프에서 사용할 수는 없습니다 (범위 기반이거나 그렇지 않은 경우). 하지만이 배열을 복사 생성자 인'array myarray (Struct :: stat_arr)'을 사용하여 다른 배열을 만들 수 있습니다. 나는 이것을 설명 할 수 없다. – Vasily