2017-11-22 14 views
0

컴파일 타임 배열을 얻으려고하므로 this answer으로 오십시오.메타 프로그래밍에 관한 몇 가지 질문이 있으십니까?

  1. struct gens : gens<N-1, N-1, S...>의 구문은 무엇인가 : 그래서 여기에 두 가지 질문이 있습니다,

    #include <array> 
    #include <algorithm> 
    #include <iterator> 
    #include <iostream> 
    
    template<int ...> 
    struct seq { }; 
    
    template<int N, int ...S> 
    struct gens : gens<N-1, N-1, S...> { }; 
    
    template<int ...S> 
    struct gens<0, S...> { 
        typedef seq<S...> type; 
    }; 
    
    constexpr int f(int n) { 
        return n; 
    } 
    
    template <int N> 
    class array_thinger { 
        typedef typename gens<N>::type list; 
    
        template <int ...S> 
        static constexpr std::array<int,N> make_arr(seq<S...>) { 
        return std::array<int,N>{{f(S)...}}; 
        } 
    public: 
        static constexpr std::array<int,N> arr = make_arr(list()); 
    }; 
    
    template <int N> 
    constexpr std::array<int,N> array_thinger<N>::arr; 
    
    int main() { 
        std::copy(begin(array_thinger<10>::arr), end(array_thinger<10>::arr), 
          std::ostream_iterator<int>(std::cout, "\n")); 
    } 
    

    하지만 메타 프로그래밍에 대한 안돼서 : 아래는 대답에서 코드인가? C++ 0x에서 Delegating constructors처럼 보이지만 잘 모르겠습니다.

  2. struct seqtypedef seq<S...> type의 용도는 무엇입니까? 아, 나는 또한 템플릿에 대한 좋은 명령이 없습니다.
+1

** 1 ** 그것은 상속입니다. 'gens '은'gens '** 2에서 파생됩니다. ** 평범한'typedef'입니다. 'type' 이름은'seq '의 별칭으로 선언되었습니다. –

+0

예제는 divide와 conquer를 사용한 재귀 인 정수 시퀀스의보다 복잡한 구현입니다. 대규모의 인스턴스화 깊이를 피하는 데 사용됩니다. –

+0

더 간단한 예를 보려면 [this] (https://stackoverflow.com/a/27125297/4832499)를 참조하십시오. –

답변

1

재귀 적으로 자체 호출하는 템플릿이 있습니다.

당신이 쓰는 경우는 3이되고 그 N 들어 템플릿

template<int N, int ...S> 
struct gens : gens<N-1, N-1, S...> { }; 

을 사용하고 S의 매개 변수가 하나도 없습니다

gens<3>::type 

. 템플릿 구조체 자체는 gens<N-1, N-1, S...>에서 파생되며 여기에 gens<2,2>이됩니다. 이것은 다시 (재귀!) 자체를 호출합니다.

그래서 Gens 템플릿은 N = 2로 호출되고 S는 하나의 int : 2를 포함하는 하나의 요소가있는 목록입니다. 이제 다시 을 호출합니다. 이제`gens < 1,1,2>를 사용합니다. N 때까지 반복

때문에 씨족의 전문의, 지금은 0이된다 :

template<int ...S> 
    struct gens<0, S...> { 
    typedef seq<S...> type; 
}; 

이 전문이 호출됩니다. 그래서 여기에 우리가 얻을 < 0,0,1,2>. 따라서 N은 0이고 S는 0,1,2의 목록입니다. 이제 템플릿은 type 유형을 생성합니다. 유형은 지금 seq < 0,1,2>입니다.

gens는 재귀 적으로 파생되므로 0의 특수화는 구조체의 루트이기 때문에 상속 시퀀스에서 유형을 얻을 수 있습니다.

그래서 당신은 쓸 수 있습니다 :

gens<3>::type 

이다 :. seq<0,1,2>