A.4.3. Требования к constexpr-функциям

Чтобы функцию можно было объявить как constexpr, она должна удовлетворять нескольким требованиям. Если эти требования не выполнены, компилятор сочтет наличие спецификатора constexpr ошибкой. Требования таковы:

• все параметры должны иметь литеральный тип;

• возвращаемое значение должно иметь литеральный тип;

• тело функции может содержать только предложение return и ничего больше;

• выражение в предложении return должно быть константным;

• любой конструктор или оператор преобразования, встречающийся в выражении для вычисления возвращаемого значения, должен быть объявлен как constexpr.

На самом деле, это вполне понятные требования: у компилятора должна быть возможность встроить вызов функции в константное выражение, и при этом оно должно остаться константным. Кроме того, запрещается что-либо изменять; constexpr-функции являются чистыми, то есть не имеют побочных эффектов.

К constexpr-функциям, являющимся членами класса, предъявляются дополнительные требования:

• constexpr функции-члены не могут быть виртуальными;

• класс, членом которого является функция, должен иметь литеральный тип.

Для constexpr-конструкторов действуют другие правила:

• тело конструктора должно быть пустым;

• все базовые классы должны быть инициализированы;

• все нестатические данные-члены должны быть инициализированы;

• все выражения, встречающиеся в списке инициализации членов, должны быть константными;

• конструкторы, выбранные для инициализации данных-членов и базовых классов, должны быть constexpr-конструкторами;

• все конструкторы и операторы преобразования, используемые для конструирования данных-членов и базовых классов в соответствующем выражении инициализации, должны быть объявлены как constexpr.

Это тот же набор правил, что и для функций, с тем отличием, что возвращаемого значения нет, а, значит, нет и предложения return. Вместо возврата значения конструктор инициализирует базовые классы и данные-члены в списке инициализации членов. Тривиальные копирующие конструкторы неявно объявлены как constexpr.