2009-10-27 3 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

힙 생성자가 별도의 파일에 정의되어 있습니까? 템플릿으로는 그렇게 잘 작동하지 않습니다. –

답변

8

템플릿은 헤더 파일 내에서 100 % 정의되어야합니다. .cc/.cpp 파일에 Heap<T> 구현이있는 경우 문제가 발생합니다. 모든 코드를 헤더 파일로 옮기면 문제가 해결됩니다.

+0

또한 실제로는 # – Cogwheel

+0

@Cogwheel 헤더에 구현을 # 포함하여 물리적으로 분리하여 유지할 수 있지만 사실 .cpp 파일을 포함하는 것은 일반적으로 코드에서 잘못된 기호입니다. 나는 1) .h의 모든 것 또는 2) .inl 파일에 코드를 넣는 것을 선호한다. 다른 파일 확장자를 사용하면 의도가 무엇인지 알 수 있습니다. – JaredPar

+0

@JaredPar, 예. 나는 보통 .inl을 사용한다. – Cogwheel

3

C++ 표준에 따르면, 당신은 따라서 export 키워드를 사용할 수 있습니다

export template<typename foo>... 

그러나, 대부분의 컴파일러는이 기능을 지원하지 않습니다. C++ FAQ는 더 많은 정보를 가지고 있습니다 : http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14

실제로 신뢰할만한 것에 대한 JaredPar의 대답을보십시오.

+0

"수출"은 표준위원회가 사전 경험없이 갇힌 것들 중 하나였습니다. 구현하기가 어렵고 누구나 실제로 원하는 것을 수행하지 않는 것 같습니다. –