неопределенная ссылка на

Возможный дубликат:
Шаблоны C ++, неопределенная ссылка

У меня есть очень простая программа, состоящая из трех файлов, которая строит векторы из простых массивов:

//create.hpp

#ifndef CREATE_HPP_
#define CREATE_HPP_

#include <vector>

using namespace std;

template<class T>
vector<T> create_list(T uarray[], size_t size);

#endif /* CREATE_HPP_ */

//create.cpp

#include "create.hpp"
template<class T>
vector<T> create_list(T uarray[], size_t size){
vector<T> ulist(uarray, uarray + size);
return ulist;
}

//main.cpp

#include <vector>
#include <iostream>

#include "create.hpp"
using namespace std;int main(){
char temp[] = { '/', '>' };
vector<char> uvec = create_list<char>(temp, 2);

vector<char>::iterator iter=uvec.begin();
for(;iter != uvec.end();iter++){
cout<<*iter<<endl;
}

return 0;
}

Процесс сборки выглядит следующим образом:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o create.o create.cpp
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o main.o main.cpp
g++ -o main.exe main.o create.o

При сборке программы я получаю эту ошибку:

main.o: In function `main':
../main.cpp:18: undefined reference to `std::vector<char, std::allocator<char> > create_list<char>(char*, unsigned int)'

Эта программа действительно проста. Тем не менее, компиляции прошли успешно, но ссылка не удалась. Затем я перемещаю весь код в один файл, и все работает как шарм. Кто-нибудь может помочь мне понять это?

1

Решение

Да. Ответ сложный. Это связано с тем, как на самом деле работают шаблоны в C ++.

Краткий ответ: полное определение шаблона должно быть в заголовочном файле, или у вас должно быть явное создание экземпляра (например, http://msdn.microsoft.com/en-us/library/by56e477(v=vs.80).aspx) для данного типа в файле CPP.

Длинный ответ (причина): шаблоны не являются кодом, который может быть скомпилирован в двоичный файл (объект). Они являются просто «рецептом для создания кода», и код может быть создан только в процессе создания экземпляра. По этой же причине неточное использование шаблонов может привести к увеличению времени компиляции и увеличению размера необходимых двоичных файлов.

6

Другие решения

Вы определили свой шаблон в отдельном .cpp файл. Каждый файл составляется отдельно. Ваш create.cpp не содержит никакого запущенного кода, поэтому он отбрасывается компилятором. Позже, на этапе связывания, когда компоновщик пытается связать двоичный файл main.cpp с create_list, он не может найти его в других скомпилированных объектах, поэтому вы получаете эту ошибку. Чтобы решить эту проблему, вам нужно создать хотя бы один раз экземпляр вашего шаблона в вашем create.cpp или иметь реализацию внутри заголовочного файла.

3