2014-12-28 32 views
3

我正在看this講座,其中下面的例子(@ 29.43)被呈現爲專業化:這是一個專業化?

template<class T> 
struct rank 
{ 
    static const size_t value = 0u; 
} 

// partial specialization 
template<class U, size_t N> 
struct rank<U[N]> 
{ 
    static const size_t value = 1 + rank<U>::value; 
} 

我期望編譯錯誤,抱怨結構是incombatible和具有第二一個的聲明太多的模板參數。 以上是不是一個錯誤?

+1

這不是一個特例,只是一個模板聲明。 –

+8

@πάνταῥεῖ呃...什麼?這是一個專業化。您不能擁有多個具有相同名稱的不同模板類,並且代碼不會嘗試這樣做。 – hvd

+0

@doc GCC 4.8.3不給出這樣的錯誤,假設添加了缺失的分號並且包含''以使'size_t'可用。 – hvd

回答

10

專業化程序本身可以有模板參數。具有模板參數的專業化稱爲部分專業化。

template<class T> 
struct rank { ...1 }; 

rank<T>裝置是一個類,並且除非另有規定,...1是類的定義。

template<class U, size_t N> 
struct rank<U[N]> { ...2 }; 

是「另有規定」:這意味着,如果在rank<T>T可以爲某種類型的U和一些恆定N被寫爲U[N],然後...2是類的定義。

你可以使用它,如rank<int[2]>,它將使用第二類定義U = intN = 2

+1

我會接受這個答案,因爲它糾正了它的兩個前輩,並給出了第一個正確的見解 –

4

這不是錯誤,因爲它是有效的。

[C++11: 14.5.5/1]:主類模板聲明是其中類模板名稱是標識符的聲明。類模板名稱爲simple-template-id的模板聲明是在simple-template-id中命名的類模板的部分特化。當特化中的參數與部分特化(14.5.5.1)中給出的參數相匹配時,類模板的部分特化提供了替代主模板的替代定義。 [..]

有根本沒有規則,禁止它,事實上,該標準包含正是這種情況的一個例子:

[C++11: 14.5.5/3]:[示例:

template<class T1, class T2, int I> class A { };    // #1 
template<class T, int I>   class A<T, T*, I> { }; // #2 
template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 
template<class T>     class A<int, T*, 5> { }; // #4 
template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5 

第一個聲明聲明瞭主(非特殊化)類模板。第二個和隨後的聲明聲明主模板的部分特化。末端示例]

是即使勉強相關的唯一限制是,諷刺的是,接近(雖然不是精確的),你所聲稱的相反:

[C++11: 14.5.5/8]:中的參數進行類模板部分專業化清單,適用以下限制:

  • [..]
  • 專業化的參數列表不應與主模板的隱式參數列表相同。
  • [..]

你會使用主模板和部分特化,像這樣:

int main() 
{ 
    rank<char> a; // uses the primary 
    rank<int[5]> b; // uses the partial spec. 
} 
+1

引用規範的舷梯。永遠有一個權威的參考,即使是一個稍微難以理解的參考:-) –