Стандарты C++ — что добавляли и зачем
С C++11 язык кардинально изменился: то, что раньше требовало шаблонной магии или сторонних библиотек, переехало в стандарт. Каждые три года выходит новый стандарт; знать, что в каком стандарте появилось, — это и про переносимость кода, и про подбор инструментов под задачу.
Карта темы
- C++11 — move-семантика,
auto, лямбды, smart pointers,nullptr,constexpr, потоки. - C++14 — generic-лямбды, return-type deduction, ослабленный
constexpr,std::make_unique. - C++17 — structured bindings,
if constexpr,std::optional,std::string_view, fold expressions, parallel STL. - C++20 — концепты, корутины, модули, ranges,
<=>,std::span,std::format. - C++23 —
std::expected,std::print,std::mdspan, deducingthis,std::generator. - C++26 (в работе) — рефлексия, контракты, senders/receivers,
std::execution.
C++11 — революция
Самый крупный сдвиг в истории языка. Что появилось:
- Move-семантика: rvalue-ссылки
T&&,std::move. Передача владения без копирования. Базис дляstd::unique_ptrи эффективных контейнеров. auto: вывод типа компилятором. Спас отstd::vector<std::map<std::string, int>>::const_iterator.- Лямбды:
[](int x) { return x * 2; }. Локальные функции с захватом контекста. - Smart pointers:
std::unique_ptr,std::shared_ptr,std::weak_ptr. RAII для динамической памяти. nullptr: типобезопасный заменитель макросаNULL.constexpr: вычисления во время компиляции (в C++11 — только одинreturn).- Threading:
std::thread,std::mutex,std::atomic. Первая стандартная многопоточность. - Range-based for:
for (auto x : container). - Variadic templates:
template<typename... Ts>.
C++14 — полировка
«Bug fix release» — закрыл дыры C++11:
- Generic lambdas:
[](auto x) { ... }. - Return type deduction для обычных функций:
auto foo() { return 42; }. - Ослабленный
constexpr: можноif,for, локальные переменные. std::make_unique— забыли в C++11.- Binary literals:
0b1010.
C++17 — практичные фичи
- Structured bindings:
auto [k, v] = *map.begin();. if constexpr: ветвление шаблонов без SFINAE.std::optional,std::variant,std::any— вне-стандартные ранее vocabulary types.std::string_view— non-owning view на строку. Дешёвая передача без копий.- Fold expressions:
(args + ...)— variadic-аргументы в один выражение. - Parallel STL:
std::execution::parдляstd::sortи других алгоритмов. std::filesystem— стандартизированный API для путей.
⚠️ std::string_view не владеет данными — хранение его дольше source-строки — UB.
C++20 — второй мегарелиз
Размером сравним с C++11:
- Concepts: типобезопасные ограничения на шаблоны вместо SFINAE.
template<std::integral T>
T square(T x) { return x * x; }
- Coroutines:
co_await,co_yield,co_return. Языковая поддержка stackless-корутин. - Modules:
import std;вместо#include. Решают проблемы заголовков (макросы, повторный парсинг). - Ranges:
views::filter,views::transform, ленивые композиции вместо итераторных пар. <=>(spaceship): автогенерируемые операторы сравнения.std::span— non-owning view на массив (какstring_view, но для произвольного типа).std::format— type-safe форматирование (наконец-то).constinit,consteval, расширенныйconstexpr(теперь почти везде).
⚠️ Поддержка C++20 в компиляторах и системах сборки до сих пор неполная — особенно модули. Большинство продакшен-проектов в 2026 — на C++17.
C++23 — следующий шаг
std::expected<T, E>— value-or-error без исключений, как RustResult.std::print— наконецprint("Hello {}", name);.std::mdspan— многомерный non-owning view (для научных вычислений и ML).- Deducing
this:template<typename Self> auto foo(this Self&& self). Унификация const/non-const overloads. std::generator— coroutine-based генератор для синтаксисаco_yield.
C++26 — на подходе
В работе на момент 2026:
- Reflection — статическое отражение типов и членов на этапе компиляции.
- Contracts —
pre/post/assert-условия в сигнатуре. - Senders/Receivers (
std::execution) — структурированный async, замена ad-hocstd::async. - Pattern matching —
inspectвыражения.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Считать, что C++20 production-ready везде | Модули и корутины ещё с шероховатостями в gcc/clang/msvc |
Хранить std::string_view дольше source-строки | UB — повисший view |
std::optional<T> для больших T без обдумывания | Стек раздувается; для больших объектов — указатель |
Использовать фичу без __cpp_* feature-test макроса | Сборка падает на старом компиляторе |
C++11 constexpr ≠ C++14+ constexpr | В C++11 запрещены локальные переменные и ветвления |
auto_ptr (C++03) в новом коде | Удалён в C++17, заменяется unique_ptr |
| Полагаться на TS/proposal до финального голосования | Фича может измениться или не войти |
Значение для собеседований
Знание стандартов — маркер свежести. Junior должен знать минимум C++11 фичи (move, smart pointers, лямбды). Middle должен ориентироваться в C++17 (structured bindings, optional, string_view). Senior — обсуждать C++20/23 (концепты, корутины, expected) и понимать состояние их поддержки.
Типичный неправильный ответ: «std::optional появился в C++20 вместе с концептами» — нет, в C++17.
Популярные направления:
- Какие самые важные фичи добавил C++11?
- Что появилось в C++17 и зачем нужен
std::string_view? - Что добавил C++20 и насколько он production-ready?
- Чем
std::expected(C++23) отличается от исключений? - Зачем понадобились feature-test макросы?