2013-03-03 61 views
2

如何創建標記爲錯誤的對象?它是一個部分專業的模板類。使用部分專用模板類創建對象

template<typename C, typename size_type = unsigned short> 
struct MatrixDataRect {...}; 

template<typename T, size_t H, size_t W> 
class MatrixDataRect<std::array<T,H*W>, size_t> {...}; 

int main() 
{ 
    MatrixDataRect<std::vector<double>> mat_data_vector; 
    MatrixDataRect<std::array<double,10*5>> mat_data_array; // WRONG!!!! 
    return 0; 
} 

這是錯誤的,因爲WRONG行使用第一個模板類。不是第二。 因爲編譯器不能分別給H和W分配10 * 5。

+1

爲什麼這是錯的? (在我的GCC裏沒問題) – deepmax 2013-03-03 18:39:20

+0

還有我的gcc! – 2013-03-03 18:40:38

+0

@MM .:我認爲*錯誤*對他來說意味着它不會實例化專業化 – 2013-03-03 18:40:46

回答

4
template<typename T, size_t H, size_t W> 
class MatrixDataRect<std::array<T,H*W>, size_t> {...}; 
MatrixDataRect<std::array<double,10*5>> mat_data_array; 

問題是模板參數H和W不能從調用位置推導出來。基本上,在實例化期間,編譯器將乘以5*10以產生50,然後嘗試實例化std::array<double,50>,實例化的類型然後用於實例化MatrixDataRect<std::array<double,50>>。在這一點上是不可能找出什麼HW的值都爲MatrixDataRect(是5和10',10和5?25和2?...)

由於類型推演不能應用程序,編譯器將回退到非專用版本並實例化主模板。

您可以使用的替代方法是:使專業化採取std::array和一個大小參數(作爲主要模板)。這適用於問題中的所有代碼,如果您需要這兩個維度,則可能不適用於其他成員。更改模板,以便顯式傳遞尺寸。

2

有兩個問題:

  1. 10*5被評估爲50,然後將編譯器試圖推斷H*W不能完成。他們可能是乘任何size_t值,使50

  2. 您是專業的size_t作爲第二個模板參數,當實例,因爲它不能推斷它必須被給予。否則,你只是實例化一個MatrixDataRect<std::array<double,10*5>, unsigned short>

下面將工作:

template<typename C, typename size_type = unsigned short> 
struct MatrixDataRect {...}; 

template<typename T, size_t S> 
class MatrixDataRect<std::array<T,S>, size_t> {...}; 

int main() 
{ 
    MatrixDataRect<std::vector<double>> mat_data_vector; 
    MatrixDataRect<std::array<double,10*5>, size_t> mat_data_array; 
    return 0; 
}