2009-10-27 135 views
2

我不是一個有經驗的C++程序員,我有問題編譯。我有一個使用模板堆類:C++類與模板編譯錯誤

template <class T> 
class Heap 
{ 
    public: 
    Heap(const vector<T>& values); 

    private: 
    vector<T> d; 

    // etc. 
}; 

然後在一個單獨的實現文件:

template <class T> 
Heap<T>::Heap(const vector<T>& values) 
{ 
d = values; 

for (unsigned int i = d.size()-1; i > 0; i--) Heapify(ParentIndex(i)); 
} 

// ... more implementation code ... 

最後一個main.cc文件:

int main (int argc, char *argv[]) 
{ 
    vector<int> in; 
    unsigned int i; 

    while (cin >> i) in.push_back(i); 
    Heap<int> h = Heap<int>(in); 

    return 0; 
} 

我得到這些編譯錯誤:

g++ -Wall -I/opt/local/include -c -o main.o main.cc 
g++ -Wall -I/opt/local/include -c -o heap.o heap.cc 
g++ -Wall -o heap main.o heap.o 
Undefined symbols: 
    "Heap<int>::Heap(std::vector<int, std::allocator<int> > const&)", referenced from: 
     _main in main.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 
make: *** [heap] Error 1 

爲什麼不能編譯?我認爲鏈接器說它找不到構造函數,但我知道它創建了目標文件。

+1

Heap構造函數是否在單獨的文件中定義?這對於模板來說效果不佳。 – 2009-10-27 15:03:23

回答

8

模板需要在頭文件中100%定義。如果您在.cc/.cpp文件中存在Heap<T>實現問題。將所有的代碼移動到頭文件,它應該可以解決你的問題。

+0

你也可以通過#include實現頭部 – Cogwheel 2009-10-27 15:06:42

+0

@Cogwheel來保持它們在物理上是分離的,true,但包括一個.cpp文件通常是代碼中的一個不好的簽名。我更喜歡1).h或2)將代碼放在.inl文件中。不同的文件擴展名使得它更加清晰,意圖是什麼 – JaredPar 2009-10-27 15:09:43

+0

@JaredPar,是的。我通常使用.inl。 – Cogwheel 2009-10-27 15:12:29

3

按照C++標準,因此您能使用export關鍵字:

export template<typename foo>... 

然而,大多數編譯器不支持此功能。 C++ FAQ有一些更多的信息:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14

請參閱JaredPar的答案,確實是可靠的。

+0

「出口」是標準委員會在沒有任何經驗的情況下堅持的那些事情之一,它表明了這一點。這很難實現,而且似乎無論如何也不會做任何人真正想要的。 – 2009-10-27 16:53:27