2010-06-24 94 views
3

爲什麼當我調用它們時,我得到對這個類中的方法的未定義引用?我會被迫將實現包含在頭文件中,還是有另一種方法可以更好地實現這一點?對C++模板方法的函數未定義的引用

class MathHelper 
{ 
public: 
    /*! 
     Represents the ratio of the circumference of a circle to its diameter, 
     specified by the constant, p. This value is accurate to 5 decimal places. 
    */ 
    static const double pi = 3.14159; 

    template <typename T> static const T modulo(const T &numerator, const T &denominator); 
    static const double modulo(double numerator, double denominator); 
    static const float modulo(float numerator, float denominator); 
    template <typename T> static const T& clamp(const T &value, const T &min, const T &max); 
    template <typename T> static const T wrap(const T &value, const T &min, const T &max); 
    template <typename T> static bool isPowerOfTwo(T number); 
    template <typename T> static T nearestPowerOfTwo(T number); 
    static float aspectRatio(const QSize &size); 
    template <typename T> static float aspectRatio(T width, T height); 
    template <typename T> static T degreesToRadians(T degrees); 
    template <typename T> static T radiansToDegrees(T radians); 
    template <typename T> static T factorial(T n); 

private: 
    MathHelper() { } 
}; 
+0

你是否將函數定義在至少如果不在同一個頭文件中的地方? – ckv 2010-06-24 08:31:38

+0

它們在相應的.cpp文件中。我在另一篇文章中看到,對於模板方法,如果編譯器不在頭文件中,編譯器就找不到這些定義。 – 2010-06-24 08:36:11

+0

要改進問題中提供的信息:未定義的符號是什麼?模板化方法在哪裏定義?你鏈接了所有需要的文件嗎? – 2010-06-24 08:43:46

回答

2

我想解釋和回答你的問題是這樣的C++ faq lite answerthe next ones

基本上,模板模式來實例化,任何單位代碼需要它必須知道如何實例化它。因此,最簡單的方法是在頭文件中定義模板(如boost)。 C++常見問題解答提供了另一種方式來做到這一點。在我的愚見,我認爲這是很麻煩......

MY2C

+0

我想他們去.h然後。 :(感謝您的回答。 – 2010-06-25 00:23:47

+0

是的。 – neuro 2010-06-25 08:22:00

0

如果我們在相應的.cpp文件中定義的實現,那麼,這樣編譯器吐出正被編碼,我們可以使用顯式實例該程序的其餘部分使用。例如:

例如:MathHelper如果要用int 實例化,請在存在實現的相應.cpp文件中添加語句template MathHelper<int>

從這個角度來看,這種方法存在一個缺點,即每次模板類與不同的參數一起使用時,必須明確地實例化該方法。

但是我們從聲明中獲得了分離實現的所有好處,特別是當構建規模很大時。