1

模板類的成員函數可以是完全專用的,例如,爲什麼你不能部分專門化一個類成員函數?

template<class A> 
struct MyClass { 
    // Lots of other members 
    int foo(); 
}; 

template<class A> 
MyClass<A>::foo() { return 42; } 

template<> 
MyClass<int>::foo() { return 0; } 

會編譯沒有問題。請注意0​​不是模板函數,所以這不是模板函數專業化(我可以理解,部分專業化是不允許的,因爲它會與重載結合起來令人難以置信的混淆)。在我看來,上面的代碼只是爲了下面的模板專業化的縮寫:

template<class A> 
struct MyClass { 
    // Lots of other members 
    int foo(); 
}; 

template<class A> 
MyClass<A>::foo() { return 42; } 

template<> 
struct MyClass<int> { 
    // Copy all the other members from MyClass<A> 
    int foo(); 
}; 

template<> 
MyClass<int>::foo() { return 0; } 

這是正確的嗎?

在這種情況下,我不知道爲什麼一個部分專業化有類似簡寫是不允許的,即爲什麼我不能寫

template<class A, class B> 
struct MyClass { 
    // Lots of other members 
    int foo(); 
}; 

template<class A, class B> 
MyClass<A,B>::foo() { return 42; } 

template<class B> 
MyClass<int,B>::foo() { return 0; } 

的簡寫

template<class A, class B> 
struct MyClass { 
    // Lots of other members 
    int foo(); 
}; 

template<class A, class B> 
MyClass<A,B>::foo() { return 42; } 

template<class B> 
struct MyClass<int,B> { 
    // Copy all the other members from MyClass<A,B> 
    int foo(); 
}; 

template<class B> 
MyClass<int,B>::foo() { return 0; } 

由於第二個片段是合法的,第一個片段是合法的,第一個片段與其完全相同(但沒有我必須明確複製所有其他數據成員並永久保持它們),我不明白爲什麼第一個不允許。

我知道這個問題已經被問到herehere,但我不是在尋找類型爲「確實不允許」的答案。或者「這是不允許的,因爲標準說不是」,也沒有辦法規避這個問題。我想知道爲什麼該標準不允許它,即是否有一個基本的原因或未來可以允許?到目前爲止,我沒有發現任何明顯重複的問題。

+0

這個問題經常被問到。長的答案在這裏:http://www.gotw.ca/publications/mill17.htm –

+0

我可能是錯的,但我認爲這篇文章是關於專門*模板函數*。我的問題是關於專門化*模板類*的非模板*成員函數,在我看來,它實際上專門化了類而不是函數(因爲成員函數不是模板)。 – PieterNuyts

+0

MyClass (例如)是與MyClass 不同的類。嘗試爲成員函數專門化模板類的模板類型是沒有意義的。 –

回答

3

您的第一個問題的答案 - 第二個片段是否確實等同於第一個 - 是「否」。

特別是,您的評論「//從MyClass複製所有其他成員」並不真正起作用:這些成員必須保持類模板的成員以確保它們只是「按需實例化」。否則,您很可能會在您從未實際使用過的成員中獲得錯誤的早期錯誤。

(也有一個不幸的問題,在C++中並不是所有的隱式實例可以寫成等效明確的分工。)

這並不意味着我們不能拿出一個規範添加類似的功能。它只比「完全專業化」更微妙,迄今爲止,我還沒有意識到將這個標準付諸實踐的認真努力。

+0

謝謝!但是我現在有點困惑 - 我認爲無論何時創建模板類的實例,都會實例化模板類的所有非模板成員。那麼這是不是真的? – PieterNuyts

+1

成員只是「部分」實例化的類;即定義沒有被實例化;只有聲明。 (明確的部分/專業化只提供定義;它不會修改聲明。) –

+0

謝謝!很高興知道 – PieterNuyts

相關問題