собственно я описываю шаблон в файле f.h: Код (Text): template <typename T> class A { private: int x; public: A(T t); }; определяю методы в файле f.cpp: Код (Text): template <typename T> A<T>::A(T t) { x = t; } в файле main.cpp вызываю его: Код (Text): void Main() { A<long> a(3); } в итоге получаю: 1>test.obj : error LNK2019: unresolved external symbol "public: __thiscall A<long>::A<long>(long)" (??0?$A@J@@QAE@J@Z) referenced in function "void __cdecl Main(void)" (?Main@@YAXXZ) я подумал - в принципе логично. ведь шаблон - просто определение. понятно что компилятор никак не может скомпилить код для какого-то абстрактоного типа T. собственно вопрос: все методы должны быть определены в f.h? в cpp'шник никак нельзя вынести? то есть должно быть так в файле f.h: Код (Text): template <typename T> class A { private: int x; public: A(T t) { x = t; } };
Именно так. Хотя можно оставить в cpp и сделать явную специализацию: Код (Text): f.cpp template <typename X> class A { bla-bla-bla }; ... template<> class A<long>;
А чего ленятся то? Надо понимать что шаблоны не классы, а улучшенные макросы и для их конкретизации компилятор должен видеть реализацию. По-этому export - баловство.
Booster сам ты улучшенный макрос %) проблема в том, что в пределах С++, при генерации кода во время линковки, все замечательно реализуется. но как только ты пытаешься скомпилить свой модуль в .obj или .lib и потом к чему-нибудь его подключить, то нужной специализации там не окажется
GoldFinch Не понимаю, при чём здесь специализация. Случаем не путаешь чего? Подключить к чему? К Дельфи?
Booster к чему угодно, хоть к тому же С++ специализация при том, что если в .obj она будет - то ОК, если не будет - то unresolved external symbol
GoldFinch Специализация лишь частный случай, принципиально ничего не меняющий. Не спорю у экспорта есть некоторые плюсы, но лично мне они не кажутся существенными. Так важно хранить определения шаблонов в cpp? Или как обычно у нас сверхсекретная реализация?
Booster Ну можно конечно и про инкапсуляцию начать говорить и прочие религиозные штуки. В целом я согласен и меня реализация в *.hpp методов не напрягает.
Религия конечно хорошо. Только некоторые забывают что конкретизирует компилятор, а не линковщик и это правильно.
Шаблоны должны быть реализованы в одном файле и это точка(на то они и шаблоны). Мне вот итерестно то должно происходить .hpp Код (Text): <template> class SomeClass { //Бла-бла-бла //Бла-бла-бла //Бла-бла-бла }; Код (Text): .cpp //Не которая реализация Компилим как library(статическую аль динамическую) В другой проект включаем .h файл SomeClass<some type> gg; Интересно где компилятор будет брать код для типа "some type", компиляции шаблонного класса он не чего и не знал, какой ему тип данных передадут. То и есть код не будет для "some type".
а меня несколько напрягает. у меня сейчас проект - там куча классов основана на одном и том-же шаблоне, но с разными базовыми типами. в результате чтобы поставить бряк на какой-нибудь метод шаблоны - нужно прождать минут 5, пока студия найдёт все реализации шаблона т куски кода где этот бряк должен стоять. вот я и думаю - есть ли тут какой-нибудь выход.