Почему реализация и объявление classа шаблона должны быть в одном заголовочном файле?

Почему реализация и объявление classа шаблона должны быть в одном заголовочном файле? Может ли кто-нибудь из вас объяснить это на примере?

Компилятор должен иметь доступ ко всему определению шаблона (а не только к сигнатуре), чтобы генерировать код для каждого экземпляра шаблона, поэтому вам нужно переместить определения функций в свой заголовок.

Подробнее читайте в разделе «Модель включения» .

Определение шаблона classа и реализация его функций-членов должно быть видимым для каждого места, которое создает его особым типом. т.е. для создания экземпляра myTemplate вам нужно увидеть полное определение и реализацию myTemplate .

Самый простой способ сделать это – установить определение шаблона и его функций-членов в том же заголовке, но есть и другие способы. Например, вы можете поместить реализацию функций-членов в отдельный файл, который был включен отдельно. Затем вы можете включить его из первого заголовка или включить только файл реализации, в котором он был нужен.

Например, одна практика заключается в том, чтобы явно создать шаблон для отдельного набора параметров в одном .cpp-файле и объявить эти экземпляры extern в заголовке. Таким образом, эти экземпляры могут использоваться в других исходных файлах, не требуя видимости функций-членов шаблона. Однако, если вы не включите файл реализации, вы не сможете использовать другие наборы параметров шаблона.

т.е. если у вас есть myTemplate и myTemplate определенные как extern тогда вы можете использовать их в порядке, но если myTemplate не определен extern тогда вы не сможете использовать это без реализации.

Они не должны.

Необходимо, чтобы определение шаблона было видимым в момент создания экземпляра (там, где оно использовалось), чтобы компилятор мог получить class / функцию из шаблона в этот момент.

Однако чрезвычайно часто используется два файла заголовков для classов шаблонов:

 // foo_fwd.hpp template  struct Foo; // foo.hpp #include "foo_fwd.hpp" template  struct Foo { typedef std::pair type; }; 

Это позволяет тем, кому не требуется полное определение шаблона, включить несколько более легкий заголовок, например:

 //is_foo.hpp #include  #include "foo_fwd.hpp" template  struct is_foo: boost::mpl::false_ {}; template  struct is_foo< Foo >: boost::mpl::true_ {}; 

который может ускорить время компиляции.

В случае нормального classа объявления достаточно для компиляции, и соответствующие определения будут связаны .

В случае шаблонов компилятору также требуется определение для генерации кода.

Разница лучше объясняется в FAQ по C ++ .

  • Шаблоны C ++, которые принимают только определенные типы
  • Как преобразовать lambda в std :: функцию с помощью шаблонов
  • Что такое руководства по вычитанию шаблонов и когда мы должны их использовать?
  • постоянные ссылки с typedef и шаблонами в c ++
  • Как компиляторы обрабатывают массивы переменной длины
  • Специализированная специализированная специализация classа, в которой шаблонный шаблон является шаблоном
  • Инициализация статического члена в шаблоне classа
  • Ошибка «Undefined symbols» с компоновщиком простого шаблона
  • Что именно «нарушено» с помощью двухфазного экземпляра шаблона Microsoft Visual C ++?
  • Как изменить шаблоны Visual Studio для нового classа / интерфейса C #?
  • проверьте, существует ли элемент с помощью enable_if
  • Давайте будем гением компьютера.