TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #220 3.73K
​Extern template

Дисклеймер: здесь и далее в этой серии статей я буду называть "специализацией" шаблона его инстанциацию с конкретным шаблонным параметром.

Помните, как мы явно инстанцировали шаблон в файле реализации? Раз мы может сказать компилятору, чтобы он инстанцировал нужную специализацию в нужном нам файле, то очень удобно потом обращаться за кодом этой специализации конкретно в эту единицу трансляции. Потому что, как мы уже знаем, код одной и той же специализации может генерироваться во всех единицах трансляции, не вызывая при этом конфликтов и нарушения ODR(вектор интов инстанцируется много где, но никогда эти специализации не конфликтуют при линковке). Тут аналогия с inline сущностями.

В общем, хочется иметь один образцово-показательный код в одной TU и обращаться за нужными символами туда.

И такой инструмент есть!

Называется extern template declaration. Этот пост, а также несколько предыдущих и следующих, посвящается нашему олду @PyXiion и его просьбе разобрать этот вопрос.

Идея очень похожа на extern объявления других сущностей. С его помощью обеспечивается внешнее связывание и оно помогает компилятору понять, что такая сущность в программе есть, просто она описана в другой единице трансляции. Это значит, что на этапе линковки компилятор может посмотреть в эту самую другую TU и найти там все, что нужно для генерации полноценного кода.

Синтаксис следующий:

extern template class-key template-name <argument-list>;

Все то же самое, что и при явной инстанциации, только спереди добавляем extern. Фича из С++11 кстати и скорее всего средний разработчик даже не представляет о ее существовании.

Что происходит, когда мы добавляем эту строчку после определения шаблона? Неявная конкретизация этой специализации запрещается. То есть даже если компилятор видит полное определение шаблона и вы создаете объект конкретной специализации, то код для нее генерироваться не будет. Вместо этого компилятор будет ждать, что он найдет нужные символы и код для них в другой единице трансляции.

В основном, эта вещь решает проблему дублирования кода специализации во всех TU, где она используется. Очевидно, что если все TU будут обращаться к одной единственной за всем нужным, а не будут генерировать все сами, то будет всего один оригинал кода и соотвественно размер бинаря уменьшится. Как и время компиляции собственно.

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

Learn new things. Stay cool.

#cppcore #cpp11 #template #compiler
  • 👍 19
  • ❤ 5
  • 🔥 5
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 →