Функция constexpr не обязана возвращать константное выражение?

С++ Primer (пятое издание) на стр. 240 содержит примечание:

"Функция A constexpr не требуется для возвращения постоянного выражения".

Вопрос об этом задан: Может ли функция constexpr возвращать функцию be non const?. Автор этого вопроса неправильно понял примечание.

Но каково правильное понимание этого (ответы на цитируемый пост разъясняют путаницу этого автора сообщения, но не отвечают на мой вопрос)?

Ответы

Ответ 1

Функция A (non-template) constexpr должна иметь как минимум один путь выполнения, который возвращает константное выражение; формально должны существовать значения аргументов, так что "вызов функции [...] может быть оцененным подвыражением основного константного выражения" ( [dcl.constexpr]/5). Например (там же):

constexpr int f(bool b) { return b ? throw 0 : 0; }     // OK
constexpr int f() { return f(true); }     // ill-formed, no diagnostic required

Здесь int f(bool) разрешено быть constexpr, потому что его вызов с аргументом value false возвращает константное выражение.

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

template<bool B> constexpr int g() { return f(B); }    // OK
constexpr int h() { return g<true>(); }    // ill-formed, no diagnostic required

Ответ 2

A constexpr Функция должна возвращать * должна иметь путь, возвращающий константное выражение, если все параметры являются постоянными выражениями. Это действительно имеет смысл. Пример:

constexpr int square(int i){
    return i*i;
}

std::array<int, square(2)> ia; //works as intended, constant expression
int i;
std::cin >> i;
int j = square(i); //works even though i is not a constant expression
std::array<int, square(i)> ia; //fails, because square does not (and cannot)
                               //return a constant expression

* Коррекция chris.