2012-03-16 27 views
6

Tôi đang xem this SO question và tôi không thể hiểu câu trả lời hoạt động như thế nào. Tôi sẽ gửi một bản sao của mã trong một trong các câu trả lời để tham khảo:Mẫu variadic này hoạt động như thế nào?

template<int ...> struct seq {}; 

// How does this line work? 
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {}; 

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

double foo(int x, float y, double z) 
{ 
    return x + y + z; 
} 

template <typename ...Args> 
struct save_it_for_later 
{ 
    std::tuple<Args...> params; 
    double (*func)(Args...); 

    double delayed_dispatch() 
    { 
    return callFunc(typename gens<sizeof...(Args)>::type()); 
    } 

    template<int ...S> 
    double callFunc(seq<S...>) 
    { 
    return func(std::get<S>(params) ...); 
    } 
}; 

int main(void) 
{ 
    std::tuple<int, float, double> t = std::make_tuple(1, 1.2, 5); 
    save_it_for_later<int,float, double> saved = {t, foo}; 
    cout << saved.delayed_dispatch() << endl; 
} 

Phần tôi không hiểu là thế này:

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

Trong ví dụ ở return callFunc(typename gens<sizeof...(Args)>::type()); Tôi giả định rằng sizeof..(Args) sẽ là 3. Vì vậy,

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

trở thành

template<3, {}> struct gens : gens<3-1, 3-1, {}> {}; 

Đây có phải là chính xác, và nếu như vậy, những gì xảy ra từ đó?

Trả lời

7

Hãy viết xuống đệ quy bằng tay:

gens<3> : gens<2, 2> 
gens<3> : gens<2, 2> : gens<1, 1, 2> 
gens<3> : gens<2, 2> : gens<1, 1, 2> : gens<0, 0, 1, 2> 

Các đệ quy dừng vì sự chuyên môn hóa một phần cho 0:

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

// first 0 consumed by the partial specialization 
// S = 0,1,2 
struct gens<0, 0, 1, 2> { 
    typedef seq<0, 1, 2> type; 
} 
+0

Cảm ơn bạn. Sử dụng đệ quy theo cách đó thực sự đã ném tôi đi. –

+0

Cảm ơn, tôi hoàn toàn bối rối bởi phần này. – Zeks

Các vấn đề liên quan