2011-05-16 11 views
0

가능한 중복 :정의되지 않은 참조


#!/usr/bin/make -f 
compiler = g++ 
compiler_flags = -Wall -I /usr/include/c++/4.5 
debug_flags = -D DEBUG -g 
binary_filename = sort_testing.bin 

all: clean release 

release: 
    $(compiler) $(compiler_flags) main.cpp sort.o -o $(binary_filename) 
debug: sort.o 
    $(compiler) $(debug_flags) $(compiler_flags) main.cpp sort.o -o $(binary_filename) 
run: 
    ./$(binary_filename) 
clean: 
    rm -f *.o $(binary_filename) 
sort.o: 
    $(compiler) $(debug_flags) $(compiler_flags) -c sort.cpp 
:

Why can templates only be implemented in the header file?

여기에 내 메이크 파일의


./make clean debug 
rm -f *.o sort_testing.bin 
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 -c sort.cpp 
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 main.cpp sort.o -o sort_testing.bin 
/tmp/ccRl2ZvH.o: In function `main': 
/home/dev/c++/sorting/main.cpp:33: undefined reference to `void sort::swap<int>;(int*, int, int)' 
collect2: ld returned 1 exit status 
make: *** [debug] Error 1 

어떤 생각이 문제를 해결하는 방법 : 여기 내 문제입니다,


// sort.hpp 
#ifndef SORT_H 
#define SORT_H 

namespace sort{ 
    template<class T> void swap(T*,int,int); 
} 

#endif 

// sort.cpp 
#include "sort.hpp" 

namespace sort{ 
    template<class T> 
    void swap(T* items, int index_a, int index_b){ 
     T t = items[index_a]; 
     items[index_a] = items[index_b]; 
     items[index_b] = t; 
    } 
} 

// main.cpp 
#include <iostream> 
#include <exception> 
#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
using namespace std; 

#include "sort.hpp" 
using namespace sort; 

#define NUM_INTS 5 

int main(int argc, char** argv){ 
    try{ 
     cout << "\n\n\n"; 
     srand(time(NULL)); 
     int * int_coll = new int[NUM_INTS]; 
     for (int x = 0; x < NUM_INTS; x++) 
      int_coll[x] = rand() % 100 + 1; 
     cout << "Before swap" << endl; 
     for (int x = 0; x < NUM_INTS; x++) 
      cout << "int " << x << " == " << int_coll[x] << endl; 
     cout << "\n\n\n"; 

     cout << "Swapping ints" << endl; 
     swap<int>(int_coll, 0, 1); 

     cout << "AFter swap" << endl; 
     for (int x = 0; x < NUM_INTS; x++) 
      cout << "int " << x << " == " << int_coll[x] << endl; 
    }catch(exception& e){ 
     cout << "Exception: " << e.what() << endl; 
    } 
    return 0; 
} 

그리고 :

여기 내 C + +를 파일입니까?

+0

'swap '이 필요하지 않습니다. 타입은'int_coll'에서 추론 할 수 있습니다. – Xeo

답변

0

템플릿 정의는 동일한 파일에 있어야합니다. 그래서 헤더 파일 자체에 함수를 정의하십시오.

// sort.hpp 
#ifndef SORT_H 
#define SORT_H 

namespace sort{ 
    template<class T> void swap(T*,int,int); 
} 


#include "sort.cpp" //<--------------- this! 

#endif 
+0

이렇게하면 sort.cpp의 이름을 변경하여 실수로 빌드 도구가 빌드 및 시도하지 않도록하는 것이 유용합니다. –

1

템플릿 정의를 사용할 때 (암시 적으로 인스턴스화 될 수 있도록) 표시해야합니다 (명시 적으로 인스턴스화해야 함) .

상황에 따라 옵션 1 (및 암시 적 구체화)을 사용합니다. 이것은 당신이 헤더 파일에 (템플릿) 템플릿 정의를 이동해야 의미

// sort.hpp 
#ifndef SORT_H 
#define SORT_H 

namespace sort{ 
    template<class T> 
    void swap(T*,int,int) 
    { 
     T t = items[index_a]; 
     items[index_a] = items[index_b]; 
     items[index_b] = t; 
    } 
} 

#endif 
또는

(그러나 일반적인 경우에 유용하지 (그러나) 그 용도가 있습니다) 명시 적 템플릿 인스턴스화입니다. 여기서 sort.cpp에 정의 할 템플릿의 변형을 정의합니다.

// sort.cpp 
#include "sort.hpp" 

namespace sort{ 
    template<class T> 
     void swap(T* items, int index_a, int index_b){ 
      T t = items[index_a]; 
      items[index_a] = items[index_b]; 
      items[index_b] = t; 
     } 

    // Define an explicit function template instantiation. 
    // Here we define that the integer version of the template must exist. 
    template void swap<int>(int*,int,int); 
} 

템플릿 버전의 수를 제한하고자 할 때 유용합니다.

+0

+1 * 명시 적 함수 템플릿 인스턴스화 *는 소스 파일에 있습니다. 나는 이것을 염두에 두지 않았다. – Nawaz