>const int &r2 = i; // ok: const int& можно связать с обычным int
У указателя >p3
есть спецификатор >const
нижнего и верхнего уровня. При копировании указателя >p3
можно проигнорировать его спецификатор >const
верхнего уровня, но не тот факт, что он указывает на константный тип. Следовательно, нельзя использовать указатель >p3
для инициализации указателя >p
, который указывает на простой (неконстантный) тип >int
. С другой стороны, вполне можно присвоить указатель >p3
указателю >p2
. У обоих указателей тот же тип (спецификатор >const
нижнего уровня). Тот факт, что >p3
— константный указатель (т.е. у него есть спецификатор >const
верхнего уровня), не имеет значения.
Упражнение 2.30. Укажите по каждому из следующих объявлений, имеет ли объявляемый объект спецификатор >const
нижнего или верхнего уровня.
>const int v2 = 0;
>int v1 = v2;
>int *p1 = &v1, &r1 = v1;
>const int *p2 = &v2, *const p3 = &i, &r2 = v2;
Упражнение 2.31. С учетом объявлений в предыдущем упражнении укажите, допустимы ли следующие присвоения. Объясните, как спецификатор >const
верхнего или нижнего уровня применяется в каждом случае.
>r1 = v2;
>p1 = p2; р2 = p1;
>p1 = p3; p2 = p3;
>constexpr
и константные выраженияКонстантное выражение (constant expression) — это выражение, значение которого не может измениться и вычисляется во время компиляции. Литерал — это константное выражение. Константный объект, инициализируемый константным выражением, также является константным выражением. Вскоре мы увидим, что в языке есть несколько контекстов, требующих константных выражений.
Является ли данный объект (или выражение) константным выражением, зависит от типов и инициализаторов. Например:
>const int max_files = 20; // max_files - константное выражение
>const int limit = max_files + 1; // limit - константное выражение
>int staff_size = 27; // staff_size - неконстантное выражение
>const int sz = get_size(); // sz - неконстантное выражение
Хотя переменная >staff_size
инициализируется литералом, это неконстантное выражение, поскольку он имеет обычный тип >int
, а не >const int
. С другой стороны, хоть переменная >sz
и константа, значение ее инициализатора неизвестно до времени выполнения. Следовательно, это неконстантное выражение.
>constexpr
В большой системе может быть трудно утверждать (наверняка), что инициализатор — константное выражение. Константная переменная могла бы быть определена с инициализатором, который мы полагаем константным выражением. Однако при использовании этой переменной в контексте, требующем константного выражения, может оказаться, что инициализатор не был константным выражением. Как правило, определение объекта и его использования в таком контексте располагаются довольно далеко друг от друга.
>constexpr
. Переменные>constexpr
неявно являются константой и должны инициализироваться константными выражениями.
>constexpr int mf = 20; //