2017-06-18 77 views
3

我在https://stackoverflow.com/a/36132696/3206356中找到了一個代碼,我試了一下。它有效,但我不完全理解那裏發生的事情。參數取決於整型模板的構造函數的模板參數推導技巧

我從下面這個鏈接複製代碼:

template <size_t N, class = std::make_index_sequence<N>> 
class Vector; 

template <size_t N, size_t... Is> 
class Vector<N, std::index_sequence<Is...>> 
{ 
private: 
    std::array<double, N> vals; 

    template <size_t > 
    using double_ = double; 
public: 
    Vector(double_<Is>... vals) 
    { 
     ... 
    } 
}; 

例如,我們嘗試使用它旁邊的方式:

Vector<3> a(1.0, 2.0, 3.0); 

如何類型推演在這裏工作?

p.s. 據我瞭解,當編譯器看到這條線時,首先它試圖推導出專業化的類型。它推導出N爲3和Is爲空序列,然後在找不到合適的構造函數時失敗。通用模板沒有定義,所以編譯器也必須在這裏失敗。但接下來會發生什麼?

+0

不,它演繹N作爲3,然後第二個參數爲'的std :: make_index_sequence <3>',默認模板參數說,因爲那是什麼。 '是...'不能是空序列(除非'N'是'0')。 –

+0

但是來自通用模板的'N'和來自專業化的'N'是不同的。當我寫道'N'被推斷爲'3'時,我的意思是專業化。而據我所知,當我們推導出專業化類型時,我們對「std :: make_index_sequence 」一無所知。我錯了嗎? – akulinich

+2

它的工作原理是這樣的。編譯器看到'Vector <3>'。它轉到*主模板*,推導出它可以的參數,並填充具有默認值的參數。這將'Vector <3>'變成'Vector <3,std :: make_index_sequence <3>>'。 *然後*爲此實例找到合適的專業化,並再次推導參數。 –

回答

1

該部分聲明(未定義)模板類Vector的默認特化。第二個模板參數默認爲0的索引序列,...,N-1

template <size_t N, class = std::make_index_sequence<N>> 
class Vector; 

默認參數是重要的,因爲它用來提供一個簡單的接口和隱藏的下一個專業化的複雜...

這個專門化是上述默認聲明的結果。索引序列的目的是攜帶Is的可變參數序列(即0 ... N -1)。

template <size_t N, size_t... Is> 
class Vector<N, std::index_sequence<Is...>> 
{ 

定義足夠的存儲

private: 
    std::array<double, N> vals; 

提供從一個爲size_t所述序列Is的翻譯成的類型的裝置(在這種情況下,雙)

template <size_t > 
    using double_ = double; 

public: 

定義了構造採取double_<0>double_<1> ... double_<N-1>。但double<N>對於任何Ndouble的類型定義。那麼這條線是在提供一個構造函數,每個Is需要一個double。即完全按照構建陣列所需的雙倍數量。實際上它很聰明。

Vector(double_<Is>... vals) 
    { 
     ... 
    } 
};