Ammendment
celtschk made a good point in the comments below the question. That is, you are not assigning to anything in your code. You are only initializing. Assigning from a const
to a constexpr
is indeed an error. So if that's what your book said, then it was not incorrect. However, this would be a strange point to make, since assigning in the other direction (from a constexpr
to a const
) is also an error. Anyway, the rest of the answer is under the assumption that when you said "assign", you meant "initialize".
End of Ammendment
Your book is incorrect (assuming you are not incorrectly paraphrasing what it said). A const integral which is initialized with a constant expression, is itself a constant expression. So i
is a constant expression, and can be used to further initialize other constant expressions.
quoth the standard, 5.19/2
A conditional-expression e is a core constant expression unless the
evaluation of e, following the rules of the abstract machine (1.9),
would evaluate one of the following expressions:
...
— an lvalue-to-rvalue conversion (4.1) unless it is applied to:
...
— a non-volatile glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression
...
However, note that a const which is not initialized with a constant expression, is of course not a constant expression:
int a = 10;
const int b = a;
constexpr int c = b; // error
Also note that this only applies to integer and enum types. Not, for example floats and doubles.
const float a = 3.14;
constexpr float b = a; // error
Although some compilers might allow that (I believe MSVC does)