2012-12-26 148 views
0

可能重複:
Undefined symbol on a template operator overloading function問題與模板C++

這裏是我的源代碼。 在Number.h

#ifndef NUMBER_H 
#define NUMBER_H 

#include <iostream> 
using std::istream; 
using std::ostream; 

template <class T> class Number; 

template <class T> 
ostream& operator<<(ostream&, const Number<T>&); 

template <class T> 
istream& operator>>(istream&, Number<T>&); 

template <class T> 
class Number{ 
public: 
    Number(const T &n) :i(n) {} 
    Number()   :i(0) {} 
    T& operator+(const Number&rhs) const; 
    T& operator-(const Number&rhs) const; 
    T& operator*(const Number&rhs) const; 
    T& operator/(const Number&rhs) const; 
    friend ostream& operator<< <T> (ostream& , const Number<T>&); 
    friend istream& operator>> <T> (istream& , Number<T>&); 
private: 
    T i; 
}; 

#endif 

而且在Number.cpp

#include "Number.h" 

template<class T> 
T& Number<T>::operator+(const Number&rhs) const 
{ 
    return i+rhs.i; 
} 

template<class T> 
T& Number<T>::operator-(const Number&rhs) const 
{ 
    return i-rhs.i; 
} 

template<class T> 
T& Number<T>::operator*(const Number&rhs) const 
{ 
    return i*rhs.i; 
} 

template<class T> 
T& Number<T>::operator/(const Number&rhs) const 
{ 
    return i/rhs.i; 
} 

template<class T> 
ostream& operator<<(ostream&os , const Number<T>&rhs) 
{ 
    return os<< rhs.i; 
} 

template<class T> 
istream& operator>>(istream&is , Number<T>&rhs) 
{ 
    return is >> rhs.i; 
} 

我無法找出原因有

undefined reference to `std::istream& operator>><double>(std::istream&,Number<double>&)' 
undefined reference to `Number<double>::operator+(Number<double> const&) const' 

錯誤等等等等

+1

[相同舊C++模板故事](HTTP://www.parashift。 com/C++ - faq-lite/templates.html) – sgarizvi

+0

也在一般undefined-references問題下描述:http://stackoverflow.com/a/12574417/777186 – jogojapan

回答

0

的所有成員函數的定義需要可用於任何翻譯實例化模板的單元。設想一個包含Number.h的文件並嘗試使用Number<int>。然後編譯器需要生成Number的所有代碼,其實例化爲Tint。如果只看到Number.h,它怎麼能這樣做?它不知道成員函數的定義。

解決的辦法是將您的成員函數(從Number.cpp)的定義放入Number.h。另外,一些人喜歡在Number.cpp命名Number.cppNumber.tpp,取而代之的#include "Number.h",把#include "Number.tpp"底部的Number.h - 基本上顛倒列入使頭部始終包括落實。

+0

非常感謝。我剛接觸'template' – user1668903

+0

並且你能解釋爲什麼'#include「Number.h」'更常見的情況是當有'template' – user1668903

+0

@ user1668903我真的不明白這個問題,我很害怕。無論何時您實例化一個模板,例如'Number ',編譯器都需要能夠生成'Number'類,並將所有出現的'T'替換爲'int'。要做到這一點,它需要能夠看到Number的所有代碼,所以頭文件必須包含頭文件和實現文件。 –

2

對於模板使用.hpp,並且不能在臨時對象上返回引用。

number.h

#ifndef NUMBER_H 
#define NUMBER_H 

#include <iostream> 
using std::istream; 
using std::ostream; 

template <class T> class Number; 

template <class T> 
ostream& operator<<(ostream&, const Number<T>&); 

template <class T> 
istream& operator>>(istream&, Number<T>&); 

template <class T> 
class Number{ 
     public: 
       Number(const T &n) :i(n) {} 
       Number()   :i(0) {} 
       T operator+(const Number&rhs) const; // Error Here return T not T& 
       T operator-(const Number&rhs) const; 
       T operator*(const Number&rhs) const; 
       T operator/(const Number&rhs) const; 
       friend ostream& operator<< <T> (ostream& , const Number<T>&); 
       friend istream& operator>> <T> (istream& , Number<T>&); 
     private: 
       T i; 
}; 

#include <number.hpp> 

#endif 

number.hpp

#ifndef NUMBER_HPP 
#define NUMBER_HPP 

template<class T> 
T 
Number<T>::operator+(const Number& rhs) const 
{ 
     return i + rhs.i; 
} 

template<class T> 
T 
Number<T>::operator-(const Number&rhs) const 
{ 
     return i-rhs.i; 
} 

template<class T> 
T 
Number<T>::operator*(const Number&rhs) const 
{ 
     return i*rhs.i; 
} 

template<class T> 
T 
Number<T>::operator/(const Number&rhs) const 
{ 
     return i/rhs.i; 
} 

template<class T> 
ostream& operator<<(ostream&os , const Number<T>&rhs) 
{ 
     return os<< rhs.i; 
} 

template<class T> 
istream& operator>>(istream&is , Number<T>&rhs) 
{ 
      return is >> rhs.i; 
} 

#endif 

的main.cpp

#include <iostream> 
    #include <number.h> 

    int 
    main(int, const char**) 
    { 
     Number<double> value(1); 
     Number<double> add(3); 

     std::cout << value + add << std::endl; 
     std::cout << value * add << std::endl; 
     std::cout << value - add << std::endl; 
     std::cout << value/add << std::endl; 
     return 0; 
} 
+0

+1爲完整:) – Potatoswatter