TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #225 3.93K
​Шаблоны не подразумевают inline

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

В прошлом посте кратко коснулись этого. Сегодня разберемся в этом подробнее.

Мы уже знаем, что в программе может быть больше одного определения шаблона и это нормально. Ровно также может быть больше одного определения inline сущности. Так есть ли между этими утверждениями связь?

Очевидно, классы не могут быть inline. Разговор здесь пойдет только про inline функции и переменные(с С++14).

Во-первых, стандарт ничего не говорит по поводу того, что шаблоны по умолчанию inline. Хотя, например, для constexpr функций и статических полей класса это явно описано.

Во-вторых, в нем есть пара слов про явные специализации

Whether an explicit specialization of a function or variable template is inline, 
constexpr, constinit, or consteval is determined by the explicit specialization and
is independent of those properties of the template. Similarly, attributes appearing
in the declaration of a template have no effect on an explicit specialization of that
template...


Эта строчка говорит нам о том, что спецификаторы, которыми помечены явные специализации, могут не совпадать со спецификаторами самих шаблонов. Значит, что шаблоны имеет смысл помечать inline и мы даже может можем изменить это поведение в явной специализации. А значит, шаблоны не подразумевают inline. Их поведение только лишь схоже с inline сущностими в плане обхода ODR. Пример из стандарта:

template<class T> void f(T) { /* ... */ } 
template<class T> inline T g(T) { /* ... */ }

template<> inline void f<>(int) { /* ... */ } // OK, inline
template<> int g<>(int) { /* ... */ } // OK, not inline


Здесь нужно быть аккуратным, потому что на явные специализации распространяется ODR. Явные специализации - уже не шаблоны, поэтому, если вы хотите поместить их в хэдэр, то нужно помечать их inline, чтобы линковщик не ругался.

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

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

Differentiate things apart. Stay cool.

#template #cppcore #cpp14 #compiler
  • 🔥 17
  • 👍 9
  • ❤ 2
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 →