>constexpr int mf = 20; // 20 - константное выражение
>constexpr int limit = mf + 1; // mf + 1 - константное выражение
>constexpr int sz = size(); // допустимо, только если size() является
> // функцией constexpr
Хоть и нельзя использовать обычную функцию как инициализатор для переменной >constexpr
, как будет описано в разделе 6.5.2, новый стандарт позволяет определять функции как >constexpr
. Такие функции должны быть достаточно просты, чтобы компилятор мог выполнить их во время компиляции. Функции >constexpr
можно использовать в инициализаторе переменной >constexpr
.
>constexpr
имеет смысл использовать для переменных, которые предполагается использовать как константные выражения.Поскольку константное выражение обрабатывается во время компиляции, есть пределы для типов, которые можно использовать в объявлении >constexpr
. Типы, которые можно использовать в объявлении >constexpr
, известны как литеральные типы (literal type), поскольку они достаточно просты для литеральных значений.
Все использованные до сих пор типы — арифметический, ссылка и указатель — это литеральные типы. Наш класс >Sales_item
и библиотечный тип >string
не относятся к литеральным типам. Следовательно, нельзя определить переменные этих типов как >constexpr
. Другие виды литеральных типов рассматриваются в разделах 7.5.6 и 19.3.
Хотя указатели и ссылки можно определить как >constexpr
, используемые для их инициализации объекты жестко ограничены. Указатель >constexpr
можно инициализировать литералом >nullptr
или литералом (т.е. константным выражением) 0. Можно также указать на (или связать с) объект, который остается по фиксированному адресу.
По причинам, рассматриваемым в разделе 6.1.1, определенные в функции переменные обычно не хранятся по фиксированному адресу. Следовательно, нельзя использовать указатель >constexpr
для указания на такие переменные. С другой стороны, адрес объекта, определенного вне любой функции, является константным выражением и, таким образом, может использоваться для инициализации указателя >constexpr
. Как будет описано в разделе 6.1.1, функции могут определять переменные, существующие на протяжении нескольких вызовов этой функция. Как и объект, определенный вне любой функции, эти специальные локальные объекты также имеют фиксированные адреса. Поэтому и ссылка >constexpr
может быть связана с такой переменной, и указатель >constexpr
может содержать ее адрес.
>constexpr
Важно понимать, что при определении указателя в объявлении >constexpr
спецификатор >constexpr
относится к указателю, а не к типу, на который указывает указатель.
>const int *p = nullptr; // p - указатель на const int
>constexpr int *q = nullptr; // q - константный указатель на int
Несмотря на внешний вид, типы >p
и >q
весьма различны; >p
— указатель на константу, тогда как >q
— константный указатель. Различие является следствием того факта, что спецификатор >constexpr
налагает на определяемый объект спецификатор >const
верхнего уровня (см. раздел 2.4.3).