Суббота, 23 Ноября 2024, 04:42

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
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
был не раз
Сейчас нет на сайте
Почитав, нашёл что некоторые компиляторы только могут компилировать код с разделёнными шаблонами(надеюсь что правильно написал :))
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг