TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #216 3.46K
Явная и неявная инстанциация шаблона

Как только компилятор видит полное определение шаблона, он может инстанцировать его с каким-то конкретным аргументом. И тут есть 2 варианта.

Вернемся к вчерашнему примеру с шаблоном корабля.


// ship.hpp

template<typename T>
struct Ship
{
// contain some fields
void TurnShip(T command) {// do some stuff}
};

// main.cpp

#include "ship.hpp"

int main() {
Ship<int> ship;
ship.TurnShip(5);
}


Согласно заветам предыдущего поста, мы перенесли все определение шаблона в хэдэр, подключили этот хэдэр в мэйн и использовали объект. И раз в мэйне мы используем объект, то в этом конкретном случае произошло неявное инстанцирование шаблона - компилятор все сделал за нас. Мы дали ему определение шаблона, укропу, кошачью жопу, ... и охапку дров, а он нам выдал плов. Точнее конкретный код, соответствующий конкретной специализации Ship<int>.

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

Представим себе, что наш корабль принимает команды только в текстовом виде. И на данный момент никаких других видов команд не предусмотрено. Тогда единственная планируемая специализация шаблона Ship будет со строками. В таком случае, мы можем заставить компилятор инстанцировать нужный нам шаблон в единице трансляции с его определением и тогда на этапе линковки компилятор сможет разрезолвить все символы и сгенерировать полноценный бинарник без ошибок. Для этого нужно добавить лишь одну строчку:


// ship.hpp
template<typename T>
struct Ship
{
// contain some fields
void TurnShip(T command);
};

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

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

template struct Ship<std::string>; // HERE IT IS!!

// main.cpp
#include "ship.hpp"
#include <string>

int main() {
Ship<std::string> ship;
ship.TurnShip(std::string{"Turn upside down"});
}


template class Ship<std::string> - яное инстанцирование шаблона. Синтаксис следующий:

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

class-key - любое из struct/class/union, должно соответствовать оному в самом шаблоне.

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

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

Но в целом, это хорошая практика. Поэтому используйте на здоровье.

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

Find a way out of your problems. Stay cool.

#cppcore #template
  • 🔥 17
  • 👍 13
  • ❤ 4
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 →