Последнее обновление:2026-10-12
constexpr и оператор «запятая» в C++20¶
C++那些事 — constexpr и comma expr¶
C++20 привнёс ряд новых возможностей, дополнительно усиливших возможности времени компиляции и безопасность кода. В этой статье мы подробно разберём два важных изменения: обработку исключений в constexpr-функциях и deprecated-статус оператора «запятая» в операторе индексации.
Примечание: для ленивых — примеры кода и сопутствующие документы этого раздела уже выложены в сообществе (知识星球), присоединяйтесь, если интересно.
1. Изменение: поддержка обработки исключений try-catch в constexpr-функциях¶
До C++20 в constexpr-функциях нельзя было использовать блоки try-catch, и это ограничение мешало обработке на этапе компиляции для ряда контейнеров стандартной библиотеки, таких как std::array. C++20 улучшил это: разрешено использовать блоки try-catch в constexpr-функциях, причём в контексте константных выражений эти конструкции обработки исключений игнорируются. Если при вычислении константного выражения бросается исключение, компилятор сообщит об ошибке.
Главная цель этого изменения — позволить контейнерам стандартной библиотеки, например std::array, поддерживать constexpr, а также заложить основу для более полной поддержки обработки исключений на этапе компиляции в будущем.
Пример:
constexpr int SafeDivide(int a, int b) {
if (b == 0) {
throw std::runtime_error("Division by zero!"); // 当除数为0时抛出异常
}
return a / b;
}
constexpr int ComputeQuotient(int x) {
try {
return SafeDivide(100, x); // 尝试除法运算
} catch (const std::runtime_error&) {
return -1; // 捕获除零异常并返回 -1
}
}
Приведённый выше код не компилировался до C++20; как C++20 обрабатывает это поведение — можете попробовать угадать результаты двух следующих проверок:
2. Deprecated-статус оператора «запятая» в операторе индексации¶
Другое изменение в C++20 — deprecated-статус оператора «запятая» внутри оператора индексации. В ранних версиях C++ в выражении array[x, y] оператор «запятая» приводил к тому, что в качестве индекса массиву или контейнеру передавался y, а x игнорировался. Однако такое использование делает код трудным для понимания и мешает будущей реализации многомерных массивов. Поэтому начиная с C++20 оператор «запятая» в операторе индексации объявлен deprecated, если только приоритет не задан явно скобками, как в array[(x, y)].
Пример кода:
В этом примере arr[(i, j)] использует скобки, чтобы явно задать приоритет оператора «запятая» и гарантировать, что именно j передаётся массиву в качестве индекса. В C++17 запись arr[i, j] была допустима, но в C++20 такое использование вызывает предупреждение о deprecated. Таким образом можно обеспечить единообразное поведение кода и соответствие новому стандарту C++20.
Если использовать оператор «запятая», компилятор выдаст предупреждение:
common.cc:9:10: warning: top-level comma expression in array subscript is deprecated [-Wcomma-subscript]
9 | arr[i, j] = 10; // C++17 中合法,C++20 中弃用
| ^
Итоги¶
Изменения в C++20 — в частности, поддержка обработки исключений в constexpr-функциях и deprecated-статус оператора «запятая» в операторе индексации — направлены на повышение возможностей времени компиляции и читабельности кода. Если ваш код опирается на эти старые возможности, рекомендуется своевременно его скорректировать, чтобы он соответствовал новому стандарту C++20.
Похожие темы¶
- Введение в корутины C++20 | C++那些事
- Практика с channel в C++20 | C++那些事
- Концепции Concepts в C++20 | C++那些事
- Порядок байтов endian в C++20 | C++那些事
- Лямбда-выражения в C++20 (часть 1) | C++那些事
- Модули Modules в C++20 | C++那些事
- Библиотека Ranges в C++20 | C++那些事
- Дизайн и подводные камни std::span в C++20 | C++那些事
- Обзор новых возможностей C++20 | C++那些事
- [[likely]] и [[unlikely]] в C++20 | C++那些事