[英]Explicit template specialization issue
template <class T>
class Test
{
public:
template<class U> void f(); //generic function
template<> void f<char>(); //Specialization for char.
};
template <class T>
template<class U>
void Test<T>::f() //Definition of generic function
{
}
template<>
template<> void Test<char>::f<char>(){} //Definition of specialization.
int main()
{
Test<char> ob1;
ob1.f<char>(); //Works fine.
Test<int> ob2;
ob2.f<char>(); //Produces linker error.
}
鏈接器錯誤是
error LNK2019: unresolved external symbol "public: void __thiscall
Test<int>::f<char>(void)"
我的要求是:我應該能夠將任何類型傳遞給Test類,並將任何類型傳遞給函數f()。 我應該可以使用下面所有類型的組合。
Test f() -------------- int char char int int int
我可以通過定義下面的另一個函數來解決錯誤。
template<>
template<> void Test<int>::f<char>(){}
但是,將Test類作為模板的用途是什么? 如何讓它適用於所有組合?
C ++ 03,§14.7.3/ 2:
應在模板所屬的名稱空間中聲明顯式特化,或者對於成員模板,在封閉類或封閉類模板所屬的名稱空間中聲明。 應該在類模板所屬的名稱空間中聲明類模板的成員函數,成員類或靜態數據成員的顯式特化。
因此,您應該在類之外聲明您的專業化,例如:
template <class T>
class Test
{
public:
template<class U> void f(); //generic function
};
template <class T>
template <class U>
void Test<T>::f() {} //Definition of generic function
template<>
template<>
void Test<char>::f<char>(){} //Specialization.
int main()
{
Test<char> ob1;
ob1.f<char>();
Test<int> ob2;
ob2.f<char>();
}
您所面臨的問題是,你已經宣布的專業化f
對char
的Test
模板,這是不正確。 編譯器沒有檢測到錯誤,但是在所有模板實例化中,你想要為char
提供f
的特化,這讓人感到困惑和解釋:
template <typename T>
struct Test {
template <typename U> void f();
template <> void f<char>(); // <- Incorrect
};
當你寫Test<int>
編譯器實例化模板和是(誤)接受它和interepreting存在的專業化f
為char
在Test<int>
。
只需刪除該行,您將獲得要編譯的代碼。 它將僅對Test<char>::f<char>()
使用專門化,我不確定這是否是你想要的。
如果你的目的是為所有實例化類型的char
專門化f
,那是不允許的。 定義模板特化時,所有封閉模板都是專用的。 常見的解決方法是不提供特化,而是提供成員函數的不同重載:
template <typename T>
struct Test {
template <typename U> void f( U );
void f( char );
};
但是那對你沒有多大幫助,因為你不能為相同的參數提供不同的重載(在你的情況下沒有參數)。 此外,在您的情況下,您必須顯式調用模板進行區分,並且顯式請求模板的代碼不會獲取重載:
int main() {
Test<int> t;
t.f<char>(); // will call template, not "void f(char)"!!
}
如果沒有關於你真正想要實現的目標的更多細節,我就無法考慮其他可能解決問題的方法。
我的要求是:我應該能夠將任何類型傳遞給Test類,並將任何類型傳遞給函數f()。 我應該可以使用下面所有類型的組合。
為什么需要明確的專業化? 為什么你不必要地想讓你的代碼變得復雜?
以下適用於您列出的所有組合。
template <class T>
class Test
{
public:
template<class U> void f();
};
template <class T>
template<class U>
void Test<T>::f(){}
int main()
{
Test<char> ob1;
ob1.f<char>(); //Works fine. T = char, U = char
Test<int> ob2;
ob2.f<char>(); //Works fine T = int, U = char
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.