P0595 представила функцию std::is_constant_evaluated()
. В документе обсуждаются некоторые ситуации, когда содержащее выражение является выражением-константой, но компилятору не требуется оценивать его во время компиляции. Приведенный пример:
constexpr double power(double b, int x) {
if (std::is_constant_evaluated() && x >= 0) {
// ...
// return r;
} else {
// Let the code generator figure it out.
return std::pow(b, (double)x);
}
}
double thousand() {
return power(10.0, 3);
}
Компилятор может оценивать power(10.0, 3)
во время компиляции, но не обязан. Следовательно, is_constant_evaluated
возвращает false.
Поэтому в статье вводится понятие «явно оцениваемых констант»:
Наш подход заключается в том, чтобы точно определить набор выражений, которые «явно оцениваются как константы» (новая техническая фраза), и указать, что наша новая функция возвращает
true
во время вычисления таких выражений иfalse
в противном случае.В частности, мы включаем два типа выражений в наш набор выражений, «явно вычисляемых константами». Первый тип прост: выражения в контекстах, где стандарт уже требует постоянного результата, такого как размерность массива или инициализатор переменной constexpr. ...
Это имеет смысл для меня. Однако фактическая формулировка в стандарте меня смущает:
Выражение или преобразование
e
явно вычисляются константами, если они:
- константное выражение или...
Другими словами, стандарт указывает, что все константные выражения явно оцениваются константами, что (мне кажется) не включает требование, чтобы выражение появлялось в контексте, где требуется константное выражение. В предложении отмечается, что power(10.0, 3)
является основным постоянным выражением, что также является моим пониманием; это делает его постоянным выражением. Если все константные выражения явно оцениваются как константы, то кажется, что здесь is_constant_evaluated
должно возвращать true.
Как следует понимать определение в стандарте, чтобы оно имело точное значение, согласующееся с целью предложения?
Это мое любимое. Там не сказано "постоянное выражение". Там написано "постоянное выражение".†
константное выражение — это грамматический термин. Это замена для тех мест в грамматике C++, где обязательно использование константных выражений.
Например, грамматика (в частности, грамматика) для шаблона-аргумента представляет собой константное выражение (или идентификатор типа или идентификатор-выражение), поэтому это правило означает, что при оценке константного выражения, которое отображается как шаблон-аргумент, эта оценка явно оценивается как константа.
Напротив, грамматика в if constexpr
не принимает константное выражение, она просто принимает условие. Так что этого пункта недостаточно, чтобы покрыть if constexpr
, поэтому есть специальный дополнительный пункт, чтобы покрыть «условие оператора if constexpr».
† Представьте, что вам нужно ответить на этот вопрос устно. Вы слышите дефис, верно?
Не забудьте про шрифт без засечек.
Не только дефис, но и курсив. Доходим ли мы до точки, когда C++ нельзя описать вслух? Простой человеческой речи уже недостаточно?