[英]Compiler errors on partial template speciailzation (c++)
我試圖做一個簡單的局部模板專門化,但是在g ++ 4.4.7,g ++ 4.8.5,clang ++ 3.8.0上出現錯誤。 每當我提到編譯器錯誤時,我都是指所有這些的輸出,因為它們總是一致的。 我正在使用C ++ 03,沒有任何選擇地進行編譯。
編碼:
#include <iostream>
template <typename T, typename X, typename G>
struct A {};
template <typename T, typename X>
struct A<T, X, void> { A() : n(1) {} X n; T b; };
template <typename X>
struct A<X, void, void> { A() : n(2) {} X n; };
int main() {
A<int, float> one;
A<int> two;
std::cout << one.n << " | " << two.n << "\n";
return 0;
}
問題1:此代碼無法編譯。 編譯器說A<int, float>
和A<int>
是錯誤的,因為A
需要3個模板參數。 為什么?
如果我將原始聲明更改為
template <typename T, typename X = void, typename G = void>
struct A {};
代碼經過編譯,輸出為: 1 | 2
1 | 2
。
發生的情況是,編譯器首先將one
類型和two
類型與未專用的A
匹配,但是隨后它正確地決定使用希望使用的部分專用類的代碼。 但是它不需要默認值。
然后,我決定更改第一個和第二個參數,以更改最后的部分專業化:
template <typename X>
struct A<void, X, void> { A() : n(2) {} X n; };
我希望這不會改變任何東西,但是編譯器不同意。 此處報告了這3個之間最清晰的輸出:
a.cpp:7:40: error: field has incomplete type 'void'
struct A<T, X, void> { A() : n(1) {} X n; T b; };
^
a.cpp:14:10: note: in instantiation of template class 'A<int, void, void>' requested here
A<int> two;
^
1 error generated.
問題2:為什么編譯器將two
變量視為A的部分專業化實例的一部分,該實例僅專門化一個參數?
請注意,這是“第二次匹配”,因為如果我僅使用1個默認模板參數,則編譯器將回過頭來抱怨需要3個模板參數這一事實。
謝謝。
問題1:此代碼無法編譯。 編譯器說
A<int, float>
和A<int>
是錯誤的,因為A
需要3個模板參數。 為什么?
因為A
需要3個模板參數。 您將A
聲明為:
template <typename T, typename X, typename G>
struct A {};
有沒有二維或一模板參數版本的A
。 有一些版本專門針對某些類型為void
的類型,但這仍然是一個參數-並非缺少參數。
添加默認值后, A<int, float>
計算結果為A<int, float, void>
,這是有效的實例化-並選擇將n
設置為1的特殊化。
您誤會了專業化的工作原理。 專業化不會更改模板參數的數量。 這只是根據最終模板參數添加特殊功能的一種方式。
問題2:為什么編譯器將兩個變量視為
A
的部分專業化實例的一部分,該實例僅專門化一個參數?
我們有三個選擇
template <T, X, G> struct A; // the primary
template <T, X, void> struct A; // (1)
template <void, X, void> struct A; // (2)
實例化A<int>
,與添加默認參數時的A<int, void, void>
相同。 那不匹配(2)
-因為那個要求第一個參數為void
並且您的參數為int
。 (1)
比主要版本更好,因為它更專業。 但是, (1)
具有類型X
的成員,在這種情況下, X
被推導為void
(從默認參數),這是不允許的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.