На базовом уровне создание экземпляра класса шаблона только создает экземпляр определения класса, а не определения функций-членов.
Теперь явное создание экземпляра шаблона класса делает также явным образом созданнымпрямые члены (не из базового класса, без шаблонов):
[temp.explicit] # 10 (выделено мной)
An явное создание экземпляров, которое именует специализацию шаблона класса , также является явным созданием экземпляров того же вида (объявление или определение) каждого из его членов (не включая членов, унаследованных от базыклассы и члены, которые являются шаблонами), который ранее не был явно специализирован в модуле перевода, содержащем явную реализацию, при условии, что связанные ограничения, если таковые имеются, этого члена удовлетворяются аргументами шаблона явной реализации ([temp.constr.decl], [temp.constr.constr]), за исключением случаев, описанных ниже.[Примечание: Кроме того, обычно это будет явное создание определенных зависящих от реализации данных о классе.- примечание конца]
Примечание:
Expl.текущий месяц декларация = extern template MyClass<Args>;
, экспл.текущий месяц определение = template MyClass<Args>;
Но , это делается только для членов, которые на самом деле определены в момент создания экземпляра:
[temp.explicit] # 11 (выделение мое)
Явное определение экземпляра, которое именует специализацию шаблона класса, явно создает экземпляр специализации шаблона класса и являетсяявное определение экземпляра только тех членов, которые были определены в момент создания .
Так как вы сделали явное определение экземпляра в заголовке (который включен источникомфайл), определения функций-членов приходят после вашего явного создания экземпляра шаблона класса, поэтому эти функции не также явно создаются.
Поэтому желательновыполнять только (не extern
) явное создание экземпляра шаблона класса в конце исходного файла, который полностью определяет все в нем.Заголовочный файл, безусловно, не в том месте.