2017-04-16 6 views
0

와 템플릿을 사용하는 동안 I 헤더 파일 global.h 선언 함수 transposeC++ 아래와 같이 에러 "정의 참조 '기능

그러나
template <size_t M, size_t N> 
void transpose(array <array <float, N>, M>& a, array <array <float, M>, N>& b) 
{ 
    // This can be made faster 
    for (size_t i = 0; i < M; i++) 
    { 
     for (size_t j = 0; j < N; j++) 
     { 
      b[j][i] = a[i][j]; 
     } 
    } 
} 

, 다음 함수 호출 :

transpose<dim, dim>(jacobian, jacobian_transposed); 
,536,913,632 아래와 같이

undefined reference to `void transpose<23u, 23u>(std::array<std::array<float, 23u>, 23u>&, std::array<std::array<float, 23u>, 23u>&)' 

가변 dimglobal.h 정의된다 :

static constexpr const int marker_num = 10; 
static constexpr const int dim = (2 * marker_num) + 3; 

내가 this answer 발견 10

오류를 던진다. global.cpp에 함수 정의를 유지할 수있는 방법이 있습니까?

편집 :question이 질문에 대한 답변이 중복되었습니다. @Xirema의 대답과 함께 나는 세 가지 옵션이 있음을 깨달았습니다. 1) 헤더에 함수를 구현합니다.

2) 확장자가 '.ipp'인 파일에 함수를 구현하고 헤더 내에 포함합니다. (내가) 가장 좋은 코딩 관행을 따르도록 노력하고

template <size_t M, size_t N> 
void transpose(array <array <float, N>, M>& a, array <array <float, M>, N>& b) 
{ 
    // This can be made faster 
    for (size_t i = 0; i < M; i++) 
    { 
     for (size_t j = 0; j < N; j++) 
     { 
      b[j][i] = a[i][j]; 
     } 
    } 
} 
template void transpose(array <array <float, dim>, dim>& a, array <array <float, dim>, dim>& b); 
template void transpose(array <array <float, dim>, 2>& a, array <array <float, 2>, dim>& b); 

위의 최선의 방법입니다 :

3) 세 번째 옵션은 같은 명시 적 인스턴스화입니까?

답변

3

템플릿 정의는 .cpp 파일로 구현할 수 없습니다. 은 헤더에이 필요합니다.

그러나 함수의 선언 및 정의를 두 개의 다른 파일로 분리하려는 합리적이고 논리적 인 사람이라면 사용할 수있는 해결 방법이 있습니다.

컴파일러에서 인식하지 못하는 파일 확장명 (.ipp)을 사용하여 파일을 구현 한 다음 헤더 파일 끝에 #include "impl.ipp" (또는 파일 이름 같이 가라.) 이렇게하면 템플릿을 올바르게 사용할 수 있습니다.

+0

구현을 헤더로 옮기는 것이 좋지 않은 것으로 간주됩니까? 또한, 확장자가 .ipp 인 파일을 모든 컴파일러에서 사용할 수 있습니까? 이것은 헤더 파일 방법보다 나은가요? –

+1

@skr_robo 헤더에는 * 필요 *하지 않지만 여러 파일에 걸쳐 구현을 공유하려면 모든 사용자가 구현을 볼 수 있어야합니다. C++ 컴파일러는 구현 파일의 이름에 상관하지 않습니다. '#include' 문을 찾아 내면 파일을 찾아서 컴파일되는 파일에 효과적으로 붙여 넣습니다. Excel이나 Matlab에서 csv 파일을 배열로로드하는 악의적 인 트릭을 포함하여 구문 적으로 올바른 파일을'# include '할 수 있습니다. 원한다면 구문 적으로 부정확 한 파일을 포함 할 수 있지만 컴파일러는 나중에 그것을 질식시킵니다. – user4581301

+0

오케이. 나는 어느 것이 더 전문적인 접근인지보기 위해 노력하고 있습니다. 편집을 참조하십시오. –