Имя для описания аргумента функции consteval, известного во время компиляции, но не constexpr

Аргумент consteval функция:

  • вроде как известно во время компиляции
  • но это не constexpr

Мотивация такого поведения объясняется Эндрю Саттоном в его статье " Перевод и оценка: ментальная модель для метапрограммирования во время компиляции", как указано в этом сообщении SO.


Вы можете вернуть аргумент из consteval функции и использовать ее как constexpr:

consteval int foo(int n) {
    return n;
}

constexpr int i = foo(9);

Но вы не можете использовать его как constexpr внутри consteval сама функция:

// fails to compile
consteval int abs(int n) {
    if constexpr (n < 0) {
        return -n;
    }
    else {
        return n;
    }
}

Выше не удается скомпилировать, поскольку п это неconstexpr.

Конечно, вы можете использовать простое if, которое будет оцениваться во время компиляции:

// compiles
consteval int abs(int n) {
    if (n < 0) {
        return -n;
    }
    else {
        return n;
    }
}

constexpr int i = -9;
constexpr int num = abs(i);

Это вопрос терминологии:

Есть ли обычно используемое имя, которое будет известно во время компиляции, но не является постоянным выражением?

1 ответ

Решение

TL;DR: Нет, в стандарте C++ для этого нет термина.

Что касается стандарта, то "известно во время компиляции" не имеет значения. Есть понятие "постоянное выражение" и есть понятие "постоянная оценка".

Функция constexpr (функция, объявленная с constexpr или consteval) можно вызывать в контексте постоянного выражения. Контекст константного выражения - это место, где язык требует, чтобы выражение было константным выражением. Аргументы шаблона, инициализаторы дляconstexpr/constinit переменные и т. д. являются постоянными контекстами выражений.

Когда функции constexpr вызываются в контексте константного выражения, они производят константные выражения... или вы неправильно сконструировали свою функцию / аргументы и получили ошибку компиляции. Это почти все, что касается стандарта.

О да, есть правила для функций constexpr. Им запрещено выполнять определенные действия C++. И есть правила их вызова из контекста постоянного выражения. Но в остальном все.

Различие, о котором вы говорите, является просто результатом того, что разрешено в функции constexpr. Вы можете вернуть параметр функции constexpr, потому что возвращаемое значение функции constexpr не является грамматически постоянным выражением. Эта функция может подвергаться постоянной оценке при определенных обстоятельствах, но это почти все, что стандарт должен сказать по этому поводу.

Сам параметр не является особенным для C++. Что особенного, так это определение функции (то есть: действительна ли ваша функция в соответствии с правилами constexpr и выполняет ли эта оценка вещи, не являющиеся constexpr), как функция была вызвана (то есть: вы вызывали ее в контексте постоянного выражения), и как параметр был заполнен (т.е. был ли аргумент постоянным выражением).

В стандарте есть выражения, которые являются постоянными выражениями, и выражения, которые не являются. Но выражения, значения которых генерируются посредством вычисления константных выражений, но сами по себе не являются лингвистически константными выражениями, просто не являются концепцией, которую должен определять стандарт. Это просто ценности; находятся ли они в оценке постоянного выражения или нет, на самом деле не имеет отношения к поведению программы.

Так что у таких вещей нет названия.

Непосредственная функция (функция, объявленная с consteval) - это просто функция constexpr с парой дополнительных правил. Эти правила предотвращают утечку адреса немедленной функции (т. Е. Компиляторам не нужно создавать для них настоящие функции). И стандарт говорит, что применение немедленной функции является всегда контекстом выражения постоянная (и, следовательно, должны быть использованы в соответствии с этими правилами).

Другие вопросы по тегам