Нет разницы между шаблонами функций, определенными в пространстве имен или в области видимости класса.Также не имеет значения, находится ли внутри шаблон класса или нет.Важно то, что в какой-то момент в проекте создается экземпляр любого используемого шаблона функции (независимо от того, является ли он членом или не членом).Давайте рассмотрим различные ситуации:
- Неиспользуемые шаблоны функций не нужно создавать, поэтому их реализация не должна быть видна компилятору в любой момент времени.Это звучит скучно, но важно, например, при использовании подходов SFINAE, где шаблоны классов или функций объявлены, но не определены.
- Любой шаблон функции, который определен там, где он используется, будет создан экземпляром компилятором в форме, которая позволяет несколькоопределения в разных единицах перевода: сохраняется только один экземпляр.Важно, чтобы все различные определения были объединены, потому что вы можете обнаружить различия, если вы взяли адрес шаблона функции или использовали переменную состояния внутри шаблона функции: для каждого экземпляра должно быть только одно из них.
- Наиболее интересная настройка - это когда шаблон функции определяется как , а не при использовании шаблона функции: в этом случае компилятор не может его создать.Когда компилятор видит определение шаблона функции в другом модуле перевода, он не знает, какие аргументы шаблона нужно создать!A Улов 22 * 1011 *?Ну, вы всегда можете явно создать экземпляр шаблона один раз.Наличие нескольких явных экземпляров создаст несколько определенных символов.
Это примерно важные параметры.Часто есть веские причины, по которым вы не хотите иметь определение шаблона функции в заголовке.Например, вы не обязательно хотите перетаскивать зависимости, которых у вас не было бы иначе.Поместить определение шаблона функции в другое место и явно создать его экземпляр - это хорошо.Кроме того, вы можете захотеть сократить время компиляции, например, избегая по существу создания экземпляров всего потока ввода-вывода и библиотеки локали в каждой единице перевода, использующей поток.В C ++ 2011 были введены внешние шаблоны , которые позволяют объявлять, что определенный шаблон (шаблон функции или класс) определяется один раз для всей программы, и нет необходимости создавать его в каждом заголовке с помощьюособенно распространенные аргументы шаблона.
Более длинную версию того, что я только что сказал, включая примеры, смотрите в сообщении в блоге , которое я написал в прошлые выходные на эту тему.