TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #226 3.98K
Когда стоит использовать explicit template declaration

Мы поговорили о случае, в котором бесполезно использовать explicit template declaration. Теперь поговорим о наиболее уместном и логичном способе использования этой фичи.

Главная функция extern template - запретить компилятору неявную инстанциацию. Значит, для адекватного использования этой конструкции компилятору необходимо иметь возможность выполнить эту неявную инстанциацию. Единственным подходящим ситуации вариантом здесь будет нахождение полного определения шаблона в хэдэре, чтобы его могли видеть все заинтересованные лица(пофантизируйте в комментариях, как могло бы выглядеть лицо у единицы трансляции).

Дальше есть следующие 2 варианта - поместить все явные объявления инстанциации шаблона в этот же хэдэр и распихать по единицам трансляции. Как по мне, лучше иметь одну централизированную точку изменений, так как программисты - люди забывчивые и могут упустить момент добавления нового явного объявления и компилятор сам сделает неявную инстанциацию. Да и если помещать в разные места, то это приведет к дубликации кода. Поэтому оставляем extern template в хэдэре.

Ну и последний момент. Если есть явное объявление инстанциации, должно быть и ее явное определение. Причем это ВАЖНО. Нельзя при использовании extern template полагаться на неявную инстанциацию. В нашем случае это уже невозможно, потому что мы добавили в хэдэр с шаблоном запрет на неявную инстанциацию, но я все равно хочу на это обратить ваше внимание. Компилятор может ее оптимизировать, так что для нее больше не останется отдельно скомпилированной сущности и все вызовы просто встроятся. Тогда компановщик не сможет разрезолвить символы и будет undefined reference. Чуть позже расскажу об этом в отдельном посте.
Итак, explicit template instantiation. Мы помещаем явные определения всех нужных нам неявных специализаций в отдельный цппшник. И вот к коду в этой TU будет обращаться линкер, чтобы подставить адреса нужных вызовов. А в других TU не будет сгенерировано ничего связанного с шаблоном.

Продемонстрирую на примере:

// ship.hpp

#pragma once
#include <string>
template<typename T>
struct Ship
{
// contain some fields
void TurnShip(T command);
};

template <class T>
void Ship<T>::TurnShip(T command) {/* do stuff using command */}

extern template class Ship<std::string>; // text command
extern template class Ship<int>; // turn certain number of degrees clockwise

// ship.cpp

#include "ship.hpp"

template class Ship<std::string>;
template class Ship<int>;

// main.cpp

#include "ship.hpp"
#include <string>

int main() {
Ship<std::string> ship;
ship.TurnShip(std::string{"Turn upside down"});
Ship<int> ship1; // i know it's silly to instantiate 2 version of
// ship just to have a different style of turning,
// but stick to the goodold example
ship1.TurnShip(36'000); // just trying to make a giant whirlpool
}


Если мы отдельно скомпилируем main.cpp и посмотрим на символы объектника, то там будет только то, что связано с std::basic_string, но не с Ship. Как и было задумано.

Подводя итог: нам нужен хэдэр с полным определением шаблона и явными объявлениями extern template и сорец с явными определениями этих инстанциаций. Теперь мы можем везде тыкать наш хэдэр и ожидать уменьшения времени компиляции и меньшего размера объектников.

Choose the right way. Stay cool.

#template #compiler #cppcore
  • 👍 21
  • ❤ 9
  • 🔥 3
More from @grokaemcpp
  1. Oct 14, 2026​​Что внутри std::condition_variable? #опытным Более менее все знакомы с примитивом синхро…
  2. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  3. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  4. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  5. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  6. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →