2013-07-30 27 views
2

編譯時出現以下錯誤:g ++ main.cpp Vec.cpp -Wall -o main -I。在C++模板代碼中找不到構造函數

/tmp/cciqbEQJ.o: In function `main': 
main.cpp:(.text+0x8b): undefined reference to `Vec<double>::Vec()' 
main.cpp:(.text+0x9b): undefined reference to `Vec<double>::~Vec()' 
collect2: ld returned 1 exit status 
make: *** [all] Error 1 

我不明白,因爲我以前做過很多多源文件的程序,我從未得到這個錯誤在那裏沒有找到構造函數。似乎編譯器無法將模板代碼動態綁定到模板的實例化。另外,我在.h文件中加入了一個宏保護,但它不在下面顯示。

源代碼是下面:

Vec.cpp

#include "Vec.h" 

using namespace std; 

template<class T> 
Vec<T>::Vec() { 
    create(); 
} 


template<class T> 
Vec<T>::Vec(size_type n, const value_type& t){ 
     create(n,t); 
} 
template<class T> 
Vec<T>::Vec(const Vec& v) 
{ 
     create(v.begin(), v.end()); 
} 

template<class T> 
Vec<T>::~Vec(){ 
    uncreate(); 
} 

    template<class T> 
    void Vec<T>::create() 
{ 
data = avail = limit = 0; 
} 

    template<class T> 
    void Vec<T>::create(size_type n, const T& val) 
{ 
    data = alloc.allocate(n); 
    limit = avail = data + n; 
    uninitialized_fill(data,limit, val); 
} 

template<class T> 
void Vec<T>::create(const_iterator i, const_iterator j) { 

    data = alloc.allocate(j-i); 
    limit = avail = uninitialized_copy(i, j, data); 
} 
    template<class T> 
    void Vec<T>::uncreate() { 

      if (data) { 

        iterator it = avail; 
        while (it != data) 
          alloc.destroy(--it); 

        alloc.deallocate(data,limit-data); 
      } 
      data = limit = avail =0; 
    } 

    template<class T> void Vec<T>::grow() { 
      size_type new_size = max (2 * (limit-data), ptrdiff_t(1)); 

      iterator new_data = alloc.allocate(new_size); 
      iterator new_avail = unitialized_copy(data, avail, new_data); 

      uncreate(); 
      data = new_data; 
      avail = new_avail; 
      limit = data + new_size; 

    } 


    template<class T> void Vec<T>::unchecked_append(const T& val) { 
      alloc.construct(avail++, val); 
    } 

    template<class T> 
    void Vec<T>::push_back(const T& t){ 
        if (avail == limit) 
          grow(); 

        unchecked_append(t); 
    } 

Vec.h

template<class T> class Vec{ 
    public: 
      typedef T* iterator; 
      typedef const T* const_iterator; 
      typedef size_t size_type; 
      typedef T value_type; 

      Vec(); 
      Vec(size_type n, const T& t=T()); 

      Vec(const Vec& v); 
      Vec& operator=(const Vec& v); 

      ~Vec(); 
      void push_back(const T& t); 

      inline size_type size() const { return limit - data; } 

      inline iterator begin() {return data;} 
      inline const_iterator begin() const { return data; } 

      inline iterator end() { return limit; } 
      inline const_iterator end() const { return limit; } 

      inline T& operator[](size_type i){ 
        return data[i]; 
      } 
      const T& operator[](size_type i) const { return data[i]; } 


    private: 
      iterator data; 
      iterator limit; 
      iterator avail; 

      //facilities for memory allocation 
      allocator<T> alloc; 

      //allocate and initialize the underlying array 
      void create(); 
      void create(size_type, const T&); 
      void create(const_iterator, const_iterator); 

      //destroy the elements in the array and free the memory 
      void uncreate(); 

      //support functions for push_back 
     void grow(); 
     void unchecked_append(const T&); 
}; 

的main.cpp

int main(void) { 
    Vec<double> test; 
}    
+0

你不能把模板就像在CPP文件中一樣 –

+0

不要在'* .cpp'中使用模板。 – Synxis

+0

否則,人們應該如何定義.cpp中的任何內容?如果沒有模板,編譯器會拋出「T未定義」 –

回答

1

爲了使編譯器生成代碼,它必須即模板定義和用於模板的特定類型。

因此,在main.cpp只需添加一行#include "Vec.cpp"頂部

編譯使用 g++ main.cpp -Wall -o main -I. < - 通知Vec.cpp現在刪除。

這將確保模板聲明和實現在編譯期間一起,同時實現仍然與聲明分離。

另一種方法是包括該.cpp而在Vec.h在由juanchopanza

的SO上述評論的鏈接有關詳細信息建議參考: - Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file ?