×
Traktatov.net » Язык программирования C++. Пятое издание » Читать онлайн
Страница 56 из 714 Настройки

>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).