2011-03-05 51 views
0

有幾個問題已經與堆棧溢出相似,但似乎沒有任何東西可以直接回答我的問題。如果我正在轉貼,我很抱歉。C++ - 使用該方法的部分特化的超載模板化類方法

我想重載模板類(有2個模板參數)的幾個方法與這些方法的部分模板專業化。我一直無法弄清楚正確的語法,並開始認爲這是不可能的。我想我會在這裏張貼,看看我能否得到確認。

示例代碼遵循:

template <typename T, typename U> 
class Test 
{ 
public: 
    void Set(T t, U u); 

    T m_T; 
    U m_U; 
}; 

// Fully templated method that should be used most of the time 
template <typename T, typename U> 
inline void Test<T,U>::Set(T t, U u) 
{ 
    m_T=t; 
    m_U=u; 
} 

// Partial specialisation that should only be used when U is a float. 
// This generates compile errors 
template <typename T> 
inline void Test<T,float>::Set(T t, float u) 
{ 
    m_T=t; 
    m_U=u+0.5f; 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Test<int, int> testOne;  
    int a = 1; 
    testOne.Set(a, a); 

    Test<int, float> testTwo;  
    float f = 1.f; 
    testTwo.Set(a, f); 
} 

我知道我可以寫整個班級的部分專業化,但還挺吮吸。是這樣的可能嗎?

(我使用VS2008) 編輯:這是編譯錯誤 錯誤C2244: '測試::設置':無法定義的功能匹配到一個現有的聲明

謝謝:)

回答

1

你素描的特定問題很簡單:

template< class T > 
inline T foo(T const& v) { return v; } 

template<> 
float foo(float const& v) { return v+0.5; } 

然後從你的Test::Set實現中調用foo

如果你想要完整的概括性,那麼類似地使用帶有靜態助手成員函數的助手類,並部分地專門化該助手類。

乾杯&心連心,

+0

這是一個好主意。謝謝 :) – JBeFat 2011-03-05 20:51:58

5

你不能部分地專門化一個成員函數,而沒有定義類模板本身的局部特化。請注意,模板的部分特化是STILL模板,因此當編譯器看到Test<T, float>時,它需要對類模板進行部分特化。

-

$ 14.5.4.3/1從C++標準(2003)表示,

類模板的 構件的模板參數列表中的部分 專業化應匹配 模板參數列表 模板部分專業化。的 成員的 模板參數列表類模板部分 專業化應匹配類 模板部分特例的 模板參數列表。 A 類模板專業化是一個 不同的模板。 類模板部分專業化 的成員與 主模板的成員無關。班級模板 以需要 定義的方式使用的部分專業化成員應予以定義; 模板成員的 定義從來不會用作類模板 部分專業化成員的定義 。一個 模板部分專業化的 明確 專業化 模板的明確專業化與 模板的明確專業化相同的方式申報。

那麼標準本身給出了這樣的例子,

// primary template 
template<class T, int I> struct A { 
void f(); 
}; 
template<class T, int I> void A<T,I>::f() { } 

// class template partial specialization 
template<class T> struct A<T,2> { 
void f(); 
void g(); 
void h(); 
}; 
// member of class template partial specialization 
template<class T> void A<T,2>::g() { } 

我希望從標準的報價與示例一起回答你的問題很好。

0

還有另一種解決方案,以局部特殊化的問題,如果你不想引入額外的功能,方法或類代碼。

#include <type_traits> 

template <typename T1, typename T2> 
class C 
{ 
    void f(T1 t1); 
} 

template <typename T1, typename T2> 
void C<T1, T2>::f(T1 t1) 
{ 
    if (std::is_same<T2, float>::value) 
    // Do sth 
    else 
    // Do sth 
}