Доброго времени суток) Помогите, пожалуйста. Я вот сейчас читаю про шаблоны С++, но у меня не компилится пример.. // main.cpp Код (Text): #include <iostream> #include "grid.h" using namespace std; int main(int argc, char** argv) { Lab<int> b; getchar(); return 0; } // grid.h Код (Text): template <typename> class Lab { public: Lab(); int x; }; // grid.cpp Код (Text): #include <iostream> #include "grid.h" template <typename> Lab<t>::Lab() { std::cout << "OOO!" << std::endl; } При компиляции пишет: [Linker error] undefined reference to `Lab<int>::Lab()' Почему? Кстати, а если конструктор встроенным сделать, то все работает. как так?
1. Определение шаблона убрать из .cpp 2. template <typename> Lab<t>::Lab() - wtf? может быть template <typename t> Lab<t>::Lab() ?
Necromancer13 Код (Text): #include <iostream> #include "grid.h" template <typename t> Lab<t>::Lab() { std::cout << "OOO!" << std::endl; }
Лишь интеловский компилятор поддерживает раздельную линковку шаблонов, так что просто поместите тело функции из cpp файл в заголовочный. Код (Text): #include <iostream> template <typename> class Lab { public: Lab(); int x; }; template <typename t> Lab<t>::Lab() { std::cout << "OOO!" << std::endl; }
>[Linker error] undefined reference to `Lab<int>::Lab()' >Почему? Поскольку при компиляции файла 'main.cpp' не видно шаблонного определения Lab::Lab(), функция Lab<int>::Lab() считается внешней (определённой в другом модуле). Однако при компиляции файла 'grid.cpp' компилятор не видит обращений к функции Lab<int>::Lab() – и поэтому не создаёт такую функцию. Как уже посоветовал found, можно поместить определение в заголовочный файл, либо можно явно сказать компилятору о необходимости инстанциации Lab<int>::Lab(). // grid.cpp Код (Text): #include <iostream> #include "grid.h" template <typename t> Lab<t>::Lab() { std::cout << "OOO!" << std::endl; } // template Lab<int>::Lab(); // инстанциировать только одну функцию для 'int' template class Lab<int>; // инстанциировать весь класс для 'int'
Большое спасибо! действитель при помещении определений методов в заголовочный файл работает. Я просто думал почему-то, что все определения методов следует подключать в исходный файл
Чтобы не плодить тем, попробую здесь спросить по шаблонам, заметил, что в VS 2010 код правильный по стандарту: Код (Text): template<class OperandType,class ElPartType> class Ellement { public: ... friend std::ostream& operator<< <>(std::ostream&,const Ellement&); }; компилируется лишь при явном указании: Код (Text): using namespace std; Иначе: error C2143: syntax error : missing ';' before '<' see reference to class template instantiation 'Ellement<OperandType,ElPartType>' being compiled error C2433: '<<' : 'friend' not permitted on data declarations error C2530: '<<' : references must be initialized error C2238: unexpected token(s) preceding ';' В чем может быть проблема? И на что в данном случае так сильно влияет using namespace? Полный текст модуля: http://code.google.com/p/blockschemstudio/source/browse/trunk/RPN/Ellement.h
found Тю! Шо вы меня внатуре запутали! Код (Text): template<class, class> class Ellement; template<class OperandType,class ElPartType> std::ostream& operator<<(std::ostream&,const Ellement<OperandType,ElPartType>&); template<class OperandType,class ElPartType> class Ellement { public: ... friend std::ostream& operator<< <>(std::ostream&,const Ellement&); }; где-то так... Booster Ну, я не знаю, как работает это шаманство, но я бы так делать не стал. Судя по всему в 10-ке где-то объявлен глобальный шаблон типа template<class T> ostream& operator<<(ostream&, T); но в общем случае стандарт это не гарантирует, если я правильно помню 27.6.2.5 p.s. а я бы все-равно написал бы по-другому