Шаблоны и constexpr

Тема дорожной карты · Embedded / Систем­ный программист

C++ templates и constexpr — два инструмента zero-cost абстракции, особенно ценные в embedded, где каждый байт ROM и каждый такт CPU считаются. Templates позволяют писать generic-код, который специализируется компилятором под каждый тип отдельно, без виртуальных вызовов. constexpr смещает вычисления из runtime в compile-time: lookup-таблицы синусов, CRC-таблицы, конфигурация пинов — всё считается компилятором и попадает в flash как готовая константа.

Как это работает

Шаблоны функций (template<typename T> T abs(T x)) и классов (template<typename T> class FixedQueue { ... }) инстанцируются компилятором под каждый набор type-аргументов. В embedded это даёт type-safe контейнеры без накладных расходов на runtime checks. constexpr функции вычисляются компилятором при вызове с compile-time аргументами: constexpr uint32_t CRC32(const char* str) превращает строковый литерал в значение CRC32, попадающее прямо в .rodata. C++14 расширил constexpr (циклы, локальные переменные), C++17 добавил if constexpr (compile-time выбор кода), C++20 — concepts (типобезопасные шаблоны) и consteval (гарантированно compile-time).

Когда применять

Применяйте templates для контейнеров фиксированного размера (std::array<T, N> уже есть, можно делать свои lock-free queues, ring buffers), для алгоритмов поверх разных типов (max, clamp, swap), для type-safe wrapper-ов над регистрами (Modm, Etl). constexpr — для всего, что можно посчитать заранее: CRC-таблицы, sine/cosine lookup, унаследованные magic-numbers с пояснением. AVR-устройства часто не имеют C++ STL — пользуйтесь ETL (Embedded Template Library) как заменой.

Типичные ошибки

Бездумное использование <vector> и <string> — динамическое выделение памяти в МК = катастрофа, используйте фиксированные контейнеры. Шаблоны с тяжёлой имплементацией в .h файлах — каждое включение раздувает code size, выносите non-templated части в .cpp. constexpr на функциях с побочными эффектами — компилятор молча падает на не-constexpr вызов. RTTI и exceptions в embedded — обычно отключены (-fno-rtti -fno-exceptions), templates продолжают работать.

Связанные понятия

Полезные ресурсы