Шаблоны. Особенности работы?
1. Создаем модуль.
2. В .h модуля объявляем шаблон функции:
template <class T> void g (T g);
3. В .cpp определяем функцию:
template <class T> void g (T g)
{
//
}
4. Директивой #include включаем .h данного модуля в .cpp другого модуля (скажем формы).
5. Пишем в теле любой функции (консруктора формы) этого (в который включили) следующие строки:
{
int i;
g<int>(i);
}
Компилируется так, что ну просто душа радуется, т.е. без ошибок и даже предупреждений.
Но стоит только запустить Make, Build или Run выскакивает ошибка при линковке:
[Linker Error] Unresolved external 'void g<int>(int)' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\UNIT1.OBJ
Если же в .h модуля в котором объявлено функция добавить еще и определение, то все работает на ура:
//-------------------------------------------------------
#ifndef Unit2H
#define Unit2H
template <class T> void g (T g); // Это можно и убрать.
template <class T> void g (T g)
{
//
}
//--------------------------------------------------------
#endif
Вопрос разве это нормально? Может я что-то не знаю? Объясните в чем дело.
Буду рад любым дельным комментариям.
Это несколько нелогично, но нормально. Определения шаблонов должны включаться в заголовочный файл.
XilefNori
Это несколько нелогично, но нормально. Определения шаблонов должны включаться в заголовочный файл.
А как быть с классами? Если кто знает, помогите заставить работать вот этот код:
/*----------Unit2.h----------*/
#define Unit2H
template <class Type>
class MyClass
{
public:
Type data;
Type getData();
void setData(Type val);
};
#endif
/*----------Unit2.cpp----------*/
#include "Unit2.h"
template <class Type>
Type MyClass<Type>::getData()
{
return data;
}
template <class Type>
void MyClass<Type>::setData(Type val)
{
data=val;
return;
}
/*----main.cpp----*/
include "Unit1.h"
include "Unit2.h"
void main()
{
MyClass<int> z;
int q;
q= z.getData();
return;
}
Вот ошибка:
[Linker Error] Unresolved external 'MyClass<int>::getData()' referenced from main.obj
А как быть с классами? Если кто знает, помогите
Давай разберемся логически.
Что есть компиляция? Это преобразование кода на каком-либо языке программирования в исполняемый (объектный, машинный) код.
Как может быть скомпилирован файл .cpp если в нем шаблонные методы или методы шаблонного класса, для которых ещё не ясно во что их вообще компилировать, параметры шаблона неизвестны. Сл-но файл Unit2.cpp не компилируется (максимум в нем проверится синтаксис), а сл-но нет никакого метода MyClass<int>::getData().
Вариант решения - включить реализацию методов в заголовочный (.h) файл.
В стандарте С++ есть слово export для указания компиляции шаблонов в некоторый промежуточный код, но я не встречал пока ещё компиляторов поддерживающих это слово.