簡體   English   中英

明確的模板專業化問題

[英]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>();
}

您所面臨的問題是,你已經宣布的專業化fcharTest模板,這是不正確。 編譯器沒有檢測到錯誤,但是在所有模板實例化中,你想要為char提供f的特化,這讓人感到困惑和解釋:

template <typename T>
struct Test {
   template <typename U> void f();
   template <> void f<char>();       // <- Incorrect
};

當你寫Test<int>編譯器實例化模板和是(誤)接受它和interepreting存在的專業化fcharTest<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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM