Из того, что я собираю из this answer, результат функции constexpr
не является константным выражением, если функция еще не объявлена. Что меня удивляет, это следующий фрагмент кода:Вложенные вызовы `constexpr` перед определением в контексте константного выражения
constexpr int f();
constexpr int g() {
return f();
}
constexpr int f() {
return 42;
}
int main() {
constexpr int i = g();
return i;
}
Это компилируется без проблем и работает. Перемещение f
в определении основных триггеров error: 'constexpr int f()' used before its definition
, как и следовало ожидать.
Я предполагаю, что он работает, потому что f
был определен до вызова g
, поэтому оба вызова являются постоянными выражениями.
Почему и g()
, по-видимому, постоянные выражения, хотя f
не определяется, когда он вызывается g
? Как это описывается Стандартом?
Я тестировал это на GCC 6.1.0 и Clang 3.8.0 от Coliru.
5.20/(2.3): "if ... invocation undefined' constexpr' function "? –
Я думаю, что мы должны подчеркнуть тот факт, что функция 'constexpr' должна иметь определение только после того, как она используется« odr-used ». Поэтому, даже если 'f()' не имеет определения в 'g()', компилятор может угадать тело 'g()' с помощью простого объявления, но на самом деле вызывать 'g()', вам нужно определение 'f()', потому что вызов функции считается «odr-use». Итак, да, данный ответ действительно, но я думаю, что это то, что ОП было смущено о – KABoissonneault
См. [CWG2166] (http://wg21.link/CWG2166). –