A cv-decomposition of a type T
is a sequence of
cvi and Pi
such that T is
“cv0P0cv1P1⋯cvn−1Pn−1cvnU” for n≥0,
where
each cvi is a set of cv-qualifiers ([basic.type.qualifier]), and
each Pi is
“pointer to” ([dcl.ptr]),
“pointer to member of class Ci of type” ([dcl.mptr]),
“array of Ni”, or
“array of unknown bound of” ([dcl.array]).
If Pi designates an array,
the cv-qualifiers cvi+1 on the element type are also taken as
the cv-qualifiers cvi of the array.
The type denoted by the type-idconstint**
has three cv-decompositions,
taking U
as “int”,
as “pointer to constint”, and
as “pointer to pointer to constint”.
— end example]
The n-tuple of cv-qualifiers after the first one
in the longest cv-decomposition of T, that is,
cv1,cv2,…,cvn, 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 Pi components are either the same
or one is “array of Ni” and the other is “array of unknown bound of”,
and the types denoted by U are the same.
If a program could assign a pointer of type T** to a pointer of
type constT** (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(){constchar c ='c';
char* pc;
constchar** pcc =&pc; // #1: not allowed*pcc =&c;
*pc ='C'; // #2: modifies a const object}
A prvalue of type “pointer to cv1T” can be
converted to a prvalue of type “pointer to cv2T” if
“cv2T” is more cv-qualified than “cv1T”.
A prvalue of type “pointer to member of X of type cv1T” can be converted to a prvalue of type “pointer to member
of X of type cv2T” if “cv2T” is more cv-qualified than “cv1T”.