Почему реализация и объявление класса шаблона должны находиться в одном заголовочном файле? [Дубликат]

На этот вопрос уже есть ответ здесь:

Почему шаблоны могут быть реализованы только в заголовочном файле? 15 ответов

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

 MSalters20 сент. 2010 г., 09:05
На самом деле нередко разделять объявление и реализацию на два файла. Заголовок обычно включает файл реализации.
 Lightness Races in Orbit03 мар. 2011 г., 13:23
@MSalters: что проблематично с шаблонными классами, о чем этот вопрос. Я хотел бы, чтобы я мог понизить комментарии.
 Lightness Races in Orbit03 мар. 2011 г., 13:28
@MSalters: Хорошо, хорошо. На самом деле мне удалось прочитать ваше последнее предложение полностью назад. :)
 Anycorn20 сент. 2010 г., 08:31
они должны быть видны внутри одного и того же блока компиляции. они могут быть в разных файлах, если включены оба
 MSalters03 мар. 2011 г., 13:26
@ Томалак Герет'кал: Совсем нет. У вас есть объявление в "Foo.h" и определения в "Foo.impl". Последняя строка "foo.h" перед защитой заголовка - "#include" Foo.impl ". После запуска препроцессора больше нет разницы. Они могут находиться в разных файлах, но заканчиваются в одном и том же модуле перевода (s) - и это важно для компиляторов.

Ответы на вопрос(4)

и соответствующие определения будутсвязанный.

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

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

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

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

// foo_fwd.hpp
template <typename T, typename U> struct Foo;

// foo.hpp
#include "foo_fwd.hpp"

template <typename T, typename U> struct Foo { typedef std::pair<T,U> type; };

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

//is_foo.hpp
#include <boost/mpl/bool.hpp>
#include "foo_fwd.hpp"

template <typename Z>
struct is_foo: boost::mpl::false_ {};

template <typename T, typename U>
struct is_foo< Foo<T,U> >: boost::mpl::true_ {};

что может немного ускорить время компиляции.

видны каждому месту, в котором он создается, с отдельным типом. то есть для того, чтобы создать экземплярmyTemplate<int> вам нужно увидеть полное определение и реализациюmyTemplate.

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

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

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

Решение Вопроса

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

Для более подробной информации читайте оМодель включения.

 Lightness Races in Orbit04 сент. 2011 г., 15:57
Нет, ты не Вы можете вручную написать определение в каждом TU, но, конечно, соглашение заголовка разработано, чтобы помочь вам избежать такой ерунды. :)
 athos01 янв. 2015 г., 10:03
@LightnessRacesinOrbit Могу я спросить, что такое TU?
 athos01 янв. 2015 г., 16:12
@LightnessRacesinOrbit получил это, спасибо!

Ваш ответ на вопрос