c++ и template
| |
AlexRudkowskij | Дата: Суббота, 26 Октября 2013, 16:09 | Сообщение # 1 |
был не раз
Сейчас нет на сайте
| Здравствуйте! Суть проблемы в следующем: если подключить .cpp файл, класс с шаблоном работает. А если .h - нетю Код .h файла: Код #pragma once template<class T> class Matrix { public: Matrix(){} ~Matrix(){} T push(T object);
private: T *array; int counter; };
Код .cpp файла: Код #include "Matrix.h"
template<class T> T Matrix<T>::push(T object) { T a = object; return a; }
Ошибка построения: Код 1>------ Построение начато: проект: Matrix, Конфигурация: Debug Win32 ------ 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppBuild.targets(344,5): warning MSB8003: Could not find WindowsSDKDir variable from the registry. TargetFrameworkVersion or PlatformToolset may be set to an invalid version number. 1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: float __thiscall Matrix<float>::push(float)" (?push@?$Matrix@M@@QAEMM@Z) в функции _main 1>C:\Users\HOME\Documents\Visual Studio 2012\Projects\Matrix\Debug\Matrix.exe : fatal error LNK1120: неразрешенных внешних элементов: 1 ========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========
Как решить проблему?
|
|
| |
froex | Дата: Суббота, 26 Октября 2013, 16:24 | Сообщение # 2 |
Руководитель Froexilize team
Сейчас нет на сайте
| AlexRudkowskij, ошибка возникает в в файле main на этапе сборки. Предположу, что ты из основного файла подключаешь хэдэр для этого класса, но не задаёшь линкеру опцию включать объектный файл этого класса. Ошибка, если по-русски, объясняет, что для вызываемой функции не найдено определение - только заголовок.
Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее. Алгоритмы, программирование, оптимизация, тестирование, ведение проектов. Ищу художника, дизайнера, тестера, программистов С и С++ Обучаю процессам разработки и программированию.
|
|
| |
Archido | Дата: Суббота, 26 Октября 2013, 17:12 | Сообщение # 3 |
Сэнсэй
Сейчас нет на сайте
| Если класс темплейтный, то он полностью должен определяться и реализовываться в .h файле. Никаких .cpp.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
froex | Дата: Суббота, 26 Октября 2013, 17:27 | Сообщение # 4 |
Руководитель Froexilize team
Сейчас нет на сайте
|
Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее. Алгоритмы, программирование, оптимизация, тестирование, ведение проектов. Ищу художника, дизайнера, тестера, программистов С и С++ Обучаю процессам разработки и программированию.
|
|
| |
avolkoff | Дата: Воскресенье, 27 Октября 2013, 04:22 | Сообщение # 5 |
частый гость
Сейчас нет на сайте
| Выносить определение функций за объявление шаблонного класса можно, в заголовке, а вот определение шаблонных функций в отдельном файле кода никак... По крайней мере у меня ничего не вышло, такие же ошибки линковки, что логично)
|
|
| |
Archido | Дата: Воскресенье, 27 Октября 2013, 05:53 | Сообщение # 6 |
Сэнсэй
Сейчас нет на сайте
| Цитата avolkoff ( ) а вот определение шаблонных функций в отдельном файле кода никак... По крайней мере у меня ничего не вышло, такие же ошибки линковки, что логично) Ессно, во всем "виновата" сишная раздельная компиляция:) Поэтому все темплейты (не специализированные) должны находится в хедерах.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
froex | Дата: Воскресенье, 27 Октября 2013, 09:42 | Сообщение # 7 |
Руководитель Froexilize team
Сейчас нет на сайте
| Как же вы не поймёте. Всё можно вынести нормально. Как пример - гляньте файлы стандартных библиотек. Неужели там есть хоть одна шаблонная реализация в заголовочных файлах? Неужели, подключая заголовочные файлы стандартных библиотек, у вас происходит компиляция стандартных библиотек? Что за бред городите? Шаблон легко поддаётся раздельной компиляции. При линковке необходимо указывать объектный файл скомпилированной реализации класса. Добавлено (27.10.2013, 09:42) --------------------------------------------- Стандарт 14.7.1
Не превращайте форум в чат. Пишите более развернуто и понятно - всё равно вас попросят объяснить подробнее. Алгоритмы, программирование, оптимизация, тестирование, ведение проектов. Ищу художника, дизайнера, тестера, программистов С и С++ Обучаю процессам разработки и программированию.
|
|
| |
avolkoff | Дата: Воскресенье, 27 Октября 2013, 15:42 | Сообщение # 8 |
частый гость
Сейчас нет на сайте
| Цитата froex ( ) Как пример - гляньте файлы стандартных библиотек. Неужели там есть хоть одна шаблонная реализация в заголовочных файлах? Например, открыл "iostream" и увидел: Код // TEMPLATE CLASS basic_istream template<class _Elem, class _Traits> class basic_istream : virtual public basic_ios<_Elem, _Traits> { // control extractions from a stream buffer ............................................................................. _Myt& __CLR_OR_THIS_CALL operator>>(short& _Val) { // extract a short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to extract long _Tmp = 0; const _Nget& _Nget_fac = _USE(ios_base::getloc(), _Nget);
_TRY_IO_BEGIN _Nget_fac.get(_Iter(_Myios::rdbuf()), _Iter(0), *this, _State, _Tmp); _CATCH_IO_END
if (_State & ios_base::failbit || _Tmp < SHRT_MIN || SHRT_MAX < _Tmp) _State |= ios_base::failbit; else _Val = (short)_Tmp; }
_Myios::setstate(_State); return (*this); } ..............................................................
Как так? И да в CryEngine3, к примеру тоже не увидел чтобы код шаблонного класса был в *.cpp
Сообщение отредактировал avolkoff - Воскресенье, 27 Октября 2013, 15:43 |
|
| |
Archido | Дата: Воскресенье, 27 Октября 2013, 16:43 | Сообщение # 9 |
Сэнсэй
Сейчас нет на сайте
| froex Елы-палы, как не стыдно:) Как ты можешь скомпилировать "раздельно" обобщенный шаблон?:) Что компилятор по твоему должен делать с типом, про который он ничего не знает? Он ведь понятия не имеет, что ты подставил туда в другом .cpp файле, на то она и раздельная компиляция.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Сообщение отредактировал Archido - Воскресенье, 27 Октября 2013, 16:46 |
|
| |
avolkoff | Дата: Воскресенье, 27 Октября 2013, 17:19 | Сообщение # 10 |
частый гость
Сейчас нет на сайте
| Цитата Archido ( ) Елы-палы, как не стыдно:) Как ты можешь скомпилировать "раздельно" обобщенный шаблон?:) Что компилятор по твоему должен делать с типом, про который он ничего не знает? Он ведь понятия не имеет, что ты подставил туда в другом .cpp файле, на то она и раздельная компиляция. Логично...
|
|
| |
AlexRudkowskij | Дата: Воскресенье, 27 Октября 2013, 19:23 | Сообщение # 11 |
был не раз
Сейчас нет на сайте
| Почитав, нашёл что некоторые компиляторы только могут компилировать код с разделёнными шаблонами(надеюсь что правильно написал :))
|
|
| |
|