2011-02-26 73 views
5

我有一個類tPoint,將具有不同鹼基類型來實現,以便特定模板重載成員函數專業化

template<typename T>class tPoint{ 
    T x; 
    T y; 
public: 
    void Set(T ix, T iy){x=ix;y=iy;} 
}; 

當類型T爲int,tPoint<int>,我想一組特殊的(浮動,浮動),所以我可以在分配前將值舍入。

我認爲專業化我可以:

template<> void tPoint<int>::Set(float ix,float iy){x=ix+.5; y=iy+.5;} 

這樣編譯器抱怨有在類定義中沒有匹配的功能。

但是,如果我在班上設置聲明(浮動,浮動),那麼它說,這已經定義(當它編譯爲T =浮動)

我希望我自己清楚,這將是一個乾淨的方法這或我做錯了什麼?謝謝!

回答

5

您需要專門的類,像這樣:

template<> class tPoint<int>{ 
    int x; 
    int y; 
public: 
    void Set(int ix, int iy){x=ix;y=iy;} 
    void Set(float ix, float iy){x = ix+0.5; y = iy+0.5;} 
}; 
+0

我會專門浮動版本而不是所有的非浮動的一個:-) – AProgrammer 2011-02-26 17:55:40

+0

@AProgrammer,在OP只提到希望專注於tPoint ,但我同意他是否想要第二個「設置」多於一個班。 – 2011-02-26 18:05:57

0

使用升壓enable_if防止浮版本時使用float實例化。

0

你最好的選擇是:

template<typename T>class tPoint{ 
    T x; 
    T y; 
public: 
    void Set(T ix, T iy) { set_impl(boost::type<T>(), x, y); } 
private: 
    void set_impl(boost::type<int>, float ...); 
    template<typename U> 
    void set_impl(boost::type<U>, T ...); 
}; 
0

儘量不提供設置的默認實現()裏面的類。這樣,專注於浮動更容易。

3

您面臨的問題與T有關,可能是intfloat

如果你看一下模板類的定義,你會此話是那typename後出現在template部分相同T也表現爲參數的Set方法。

這意味着,當你說話的Point<int>那麼只有一個Set定義的方法,它有兩個int。而且每個不同的Point<T>都會有自己的Set(T,T)方法。

如果你希望有一個不同的Set方法,那麼你需要的模板類中聲明模板Set,這樣做是像這樣:

template <typename T> 
class Point 
{ 
public: 
    template <typename Num> 
    void Set(Num x, Num y); 
}; 

注意我如何不得不選擇了不同的模板參數名稱。


爲了解決你的問題,你可以介紹另一種方法,float,但你得有另一爲double,並long double ...它很快會變得困難。

最簡單的辦法,就是去暴力破解:

template <typename Integral> 
template <typename Num> 
void Point<Integral>::Set(Num x, Num y) 
{ 
    this->x = long double(x) + 0.5; 
    this->y = long double(y) + 0.5; 
} 

對於int和人,它主要是無用的,但工程。對於浮點,我們使用更大的浮點類型以避免丟失精度,然後執行舍入。

顯然,如果我們突然想要一個Point<float>,那就不太合適,因此我們需要一個基於類型特徵的更智能的解決方案。類std::numeric_limits<T>有一個is_integer,它降低了我們是否正在處理整數類型。

template <typename T> 
template <typename Num> 
void Point<T>::Set(Num x, Num y) 
{ 
    if (std::numeric_limits<T>::is_integer && 
    !std::numeric_limits<Num>::is_integer) 
    { 
    this->x = x + 0.5; 
    this->y = y + 0.5; 
    } 
    else 
    { 
    this->x = x; 
    this->y = y; 
    } 
    } 
} 

我知道這似乎愚蠢使用的東西,可以在編譯時確定的if ......不過不用擔心,編譯器是足夠聰明,數字出來編譯期時時間和優化掉if和未使用的分支完全;)

+0

謝謝,它比我期望的要複雜得多,但是你的帖子在模板專業化方面有一些新手點 – Joan 2011-02-26 19:46:22