2010-06-21 2 views
2

"정의되지 않은 참조"오류에 약간의 문제가 있습니다. 내가 코드를 게시 할 수 없습니다 만, 다음과 같이 선언하고 난 함수를 호출하고있는 방법은 다음과 같습니다C++ 템플릿 함수 인스턴스화

선언 :

template <typename T> 
int pitch_detect(deque<T>& x, int offset, int len); 

template <typename T> 
int is_voiced(
    deque<T>& x, int offset, int len, 
    double avg_energy, int pre_voice, 
    short& s_flag, 
    long nsamples 
); 

다음과 같이 내가 위의 함수를 호출하고 있습니다 :

x = is_voiced(superFrame_, cur_offset_, f_len_, 
    avgEnergy_, frame_voicing_[1], silence_flag_, nsamples_); 

y = pitch_detect(superFrame_, cur_offset_, f_len_); 

위의 문장 (함수를 호출하는 곳)은 오류로 표시됩니다. 이들은 메시지입니다 :

정의되지 않은 INT is_voiced`참조 (표준 : 양단 큐> &, INT, INT, 더블, INT, 짧은 & 긴)

정의되지 않은 참조에` 을 int로 pitch_detect (std :: deque> &, int, int) '

위의 오류를 디코딩 할 때 어떤 도움이 필요합니다. 감사합니다, Sriram

편집 : 위의 기능은 별도의 헤더와 해당 C++ 파일에 정의되어 있습니다. 내가 그들을 컴파일하고 객체 파일을 만들려고 할 때 아무런 문제가 없다. 이러한 오류는 링커 단계에서 볼 수 있습니다.

답변

3

해당 템플릿에 대한 정의를 제공 했습니까? 명시 적으로 템플릿을 인스턴스화하거나 컴파일러에서 인스턴스를 인스턴스화 할 수 있습니까?

템플릿 선언을 제공하지만 컴파일러가 동일한 번역 단위에서 정의를 보지 못하면 템플릿이 다른 번역 단위로 인스턴스화되고 호출을 생성하지만 컴파일하지 않을 것이라고 가정합니다. 그것을 할 수없는 정의를 보는 것) 특정 인스턴스화. 나중에 링크 시간에 링커가 호출을 보지만 인스턴스화를 볼 수 없으며 정의되지 않은 참조 오류로 실패합니다. 컴파일러는 암시 적으로 (이 코드를보고, 그리고 그것을 컴파일)에 대한 템플릿을 인스턴스화 당신이 is_voiced(...)를 사용할 때 다음

template <typename T> 
int is_voiced(deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples) 
{ 
    // code here 
} 

:

가장 간단한 해결책은 그냥 같이 템플릿의 선언과 정의를 가지고있다 .

컴파일러에서 템플릿을 암시 적으로 인스턴스화하지 못하게하는 경우가 있습니다 (어떤 유형이 사용되는지 알고 컴파일러에서 다른 용도를 허용하지 않으려면 비용이 많이 듭니다. 컴파일하고 하나의 번역 단위로 템플릿을 인스턴스화함으로써 컴파일 속도를 높이고 싶습니다.) 이러한 경우 번역 단위에서 사용자가 명시 적으로 인스턴스화해야합니다.

// header 
template <typename T> 
int is_voiced(deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples); 

// cpp 
template <typename T> 
int is_voiced(deque<T>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples) { 
    // code goes here 
} 
// explicit instantiation for int 
template int is_voiced(deque<int>& x, int offset, int len, double avg_energy, int pre_voice, short& s_flag, long nsamples); 

그런 다음 구현 파일을 컴파일하고 나머지 프로젝트와 연결하십시오.

참고 : 컴파일러에서 암시 적으로 인스턴스화 할 수 있도록 헤더에 전체 템플릿 정의를 제공하는 것이 좋습니다.

+0

아! 예. 그것이 문제였습니다. 템플릿을 명시 적으로 인스턴스화하지 않았습니다. 나는 템플릿에 익숙하지 않으며 배울 것이 많습니다. 문제 해결됨! David 감사합니다! – Sriram

+0

명시 적 인스턴스화를 실제로 사용해야합니까? 대부분의 경우 헤더에 템플릿 정의를 제공하고 컴파일러에서 사용시 암시 적으로 인스턴스화하는 것이 좋습니다. –

2

별도의 CPP 파일 대신 함수의 정의를 헤더 파일에 넣습니다. 링커가 중복 정의에 대해 불평하지 않게하려면 헤더 파일에 함수 정의에 inline 키워드를 접두사로 붙입니다.

1

g ++을 시도하지는 않았지만 형식을 명시 적으로 지정 했습니까?

x = is_voiced<PutTypeNameHere>(superFrame_, etc); 

동일한 dll/exe에서 정의 및 호출이 완료 되었습니까? 그렇지 않다면 템플릿 함수를 명시 적으로 인스턴스화해야 할 수도 있습니다.

+0

템플릿 함수를 명시 적으로 인스턴스화하지 않았습니다. 그것이 문제였습니다. 고마워! – Sriram