2010-06-21 3 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 (станд :: Deque> &, Int, Int)»

Любая помощь в расшифровке вышеуказанных ошибок можно только приветствовать. Спасибо, Sriram

Редактировать: Указанные выше функции определены в отдельном заголовке и соответствующем файле C++. У меня нет проблем, когда я пытаюсь скомпилировать их и создать объектный файл. Эти ошибки видны на стадии компоновщика.

ответ

3

Вы предоставили определения для этих шаблонов? Вы явно создаете шаблоны самостоятельно или позволяете компилятору создавать их?

Если вы предоставляете объявление шаблона, но компилятор не видит определения в одной и той же единицы перевода, предполагается, что шаблон будет создан в другой единицы перевода и будет просто генерировать вызов, но не компилировать (без видя, что это определение не может это сделать) конкретное создание. Позже в момент ссылки компоновщик увидит вызов, но не увидит экземпляр и не сработает с неопределенной ссылкой.

Самым простым решением является просто иметь декларацию шаблона и определение вместе:

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 
} 

Затем, когда вы используете is_voiced(...) компилятор неявно экземпляр шаблона для вас (он увидит код, и он будет компилировать его) ,

Есть несколько случаев, когда вы не хотите, чтобы компилятор неявно создавал экземпляры ваших шаблонов (вы знаете, какие типы будут использоваться, и вы не хотите, чтобы компилятор разрешал другие виды использования - или это дорого компилировать и ускорять компиляцию, только создавая экземпляр шаблонов в одной единице перевода). Для этих случаев вам нужно будет предоставить свой собственный явный экземпляр в единицах перевода.

// 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

Ах! Да. Это была проблема. Я явно не создавал шаблоны. Я новичок в шаблонах и многому научился. Задача решена! Спасибо, Дэвид! – Sriram

+0

Вам действительно нужно использовать явное создание экземпляра? В большинстве случаев лучше просто предоставить определение шаблона в заголовке и заставить компилятор имплицитно инстанцировать его при использовании. –

2

Поместите определения функций в файл заголовка, а не в отдельный файл CPP; и в заголовочном файле префикс определения функций с помощью ключевого слова inline, чтобы избежать компоновщика, жалующегося на дублирующие определения.

1

Я не пробовал g ++, но вы пробовали явно называть тип?

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

Являются ли определения и вызовы выполненными из той же библиотеки dll/exe? Если нет, вам может потребоваться явно указать функции шаблона с типами, с которыми вы их вызываете.

+0

Я не задавал явно шаблонные функции. Это была проблема. Черт побери! – Sriram

 Смежные вопросы

  • Нет связанных вопросов^_^