7 Expressions [expr]

7.3 Standard conversions [conv]

7.3.5 Qualification conversions [conv.qual]

A cv-decomposition of a type T is a sequence of and such that T is U” for , where each is a set of cv-qualifiers ([basic.type.qualifier]), and each is “pointer to” ([dcl.ptr]), “pointer to member of class of type” ([dcl.mptr]), “array of ”, or “array of unknown bound of” ([dcl.array]).
If designates an array, the cv-qualifiers on the element type are also taken as the cv-qualifiers of the array.
Example
:
The type denoted by the type-id const int ** has three cv-decompositions, taking U as “int”, as “pointer to const int”, and as “pointer to pointer to const int.
— end example
 ]
The n-tuple of cv-qualifiers after the first one in the longest cv-decomposition of T, that is, , is called the cv-qualification signature of T.
Two types T1 and T2 are similar if they have cv-decompositions with the same n such that corresponding components are either the same or one is “array of ” and the other is “array of unknown bound of”, and the types denoted by U are the same.
The cv-combined type of two types T1 and T2 is the type T3 similar to T1 whose cv-decomposition is such that:
  • for every , is the union of and ;
  • if either or is “array of unknown bound of”, is “array of unknown bound of”, otherwise it is ;
  • if the resulting is different from or , or the resulting is different from or , then const is added to every for .
where and are the components of the cv-decomposition of Tj.
A prvalue of type T1 can be converted to type T2 if the cv-combined type of T1 and T2 is T2.
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
:
Given similar types T1 and T2, this construction ensures that both can be converted to the cv-combined type of T1 and T2.
— 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
 ]