A cv-decomposition of a type T is a sequence of cvi and Pi such that T is
Two types T1 and T2 are similar if they have cv-decompositions with the same n such that corresponding Pi components are the same and the types denoted by U are the same.
A prvalue expression of type T1 can be converted to type T2 if the following conditions are satisfied, where cvij denotes the cv-qualifiers in the cv-qualification signature of Tj60:
T1 and T2 are similar.
For every i > 0, if const is in cvi1 then const is in cvi2, and similarly for volatile.
If the cvi1 and cvi2 are different, then const is in every cvk2 for 0 < k < i.
[ Note: If a program could assign a pointer of type T** to a pointer of type const T** (that is, if line #1 below were allowed), a program could inadvertently modify a const object (as it is done on line #2). For example,
int main() { const char c = 'c'; char* pc; const char** pcc = &pc; // #1: not allowed *pcc = &c; *pc = 'C'; // #2: modifies a const object }
— end note ]
[ Note: A prvalue of type “pointer to cv1 T” can be converted to a prvalue of type “pointer to cv2 T” if “cv2 T” is more cv-qualified than “cv1 T”. A prvalue of type “pointer to member of X of type cv1 T” can be converted to a prvalue of type “pointer to member of X of type cv2 T” if “cv2 T” is more cv-qualified than “cv1 T”. — end note ]
[ Note: Function types (including those used in pointer to member function types) are never cv-qualified ([dcl.fct]). — end note ]
These rules ensure that const-safety is preserved by the conversion.