# Type 1
* An rvalue of type “pointer to cv1 `T`” can be converted to an rvalue of type “pointer to cv2 `T`” if “cv2 `T`” is more cv-qualified than “cv1 `T`.”
# Type 2
* An rvalue of type “pointer to member of `X` of type cv1 `T`” can be converted to an rvalue of type “pointer to member of `X` of type cv2 `T`” if “cv2 `T`” is more cv-qualified than “cv1 `T`.”
# Type 3
* An expression of type `T1` can be converted to type `T2` if and only if the following conditions are satisfied:
* the pointer types are similar.
* for every `j > 0`, if `const` is in $cv_{1,j}$ then `const` is in $cv_{2,j}$ , and similarly for `volatile`.
* if the $cv_{1,j}$ and $cv_{2,j}$ are different, then `const` is in every $cv_{2,k}$ for `0 < k < j`.
* Two pointer types `T1` and `T2` are ***similar*** if there exists a type `T` and integer `n > 0` such that:
* `T1` is $cv_{1,0}$ pointer to $cv_{1,1}$ pointer to ... $cv_{1,n−1}$ pointer to $cv_{1,n}$ `T`.
* `T2` is $cv_{2,0}$ pointer to $cv_{2,1}$ pointer to ... $cv_{2,n−1}$ pointer to $cv_{2,n}$ `T`.
, where each $cv_{i,j}$ is `const`, `volatile`, `const volatile`, or nothing.
I.e., Two pointer types `T1` and `T2` are ***similar*** if they have the same (a) base type (b) the number of levels of pointer.
```c++
// p is pointer to int
// --> No cv–qualification signature
int* p
// p is const pointer to int
// --> No cv–qualification signature
int* const p
// p is volatile pointer to const pointer to int
// --> cv–qualification signature = (const)
int* const * volatile p
// p is pointer to volatile pointer to const pointer to int
// --> cv–qualification signature = (volatile,const)
int* const * volatie * p
// p is pointer to pointer to volatile const pointer to const pointer to int
// --> cv–qualification signature = (none,volatile const,const)
int* const * volatie const * * p
```
* The n-tuple of cv-qualifiers after the first in a pointer type, e.g., $cv_{1,1}$, $cv_{1, 2}$ , ... , $cv_{1,n}$ in the pointer type `T1`, is called the ***cv--qualification signature*** of the pointer type.
# Example
| level | p1 | p2 | p3 |
| :---- | :----: | :------------: | :------: |
| $cv_{i,0}$ | const | const | const |
| $cv_{i,1}$ | const | const | none |
| $cv_{i,2}$ | const | const volatile | volatile |
| $cv_{i,3}$ | none | none | none |
| level | q1 | q2 | q3 |
| :---- | :----: | :------------: | :------: |
| $cv_{i,0}$ | none | const | const |
| $cv_{i,1}$ | const | const | none |
| $cv_{i,2}$ | const volatile | const | const volatile |
| $cv_{i,3}$ | const | none | none |
1. `p1` can be converted to `q1`.
2. `p2` cannot be converted to `q2`.
2. `p3` cannot be converted to `q3`.
For example:
```c++
#include <iostream>
int main() {
int value = 123;
int * r = &value;
int * * volatile s = &r;
int * * volatile * t = &s;
int * * volatile * * const p3 = &t;
int * * const volatile * * const q3 = p3; // Error
// Silence “unused variable” warnings
(void)r;
(void)s;
(void)t;
(void)p3;
(void)q3;
return 0;
}
```
# Bottom line
1. Qualification conversion only focuses on mid-level cv-qualifiers.
1. In other words, qualification conversion can only add cv-qualifiers at levels other than the first in multi-level pointers.
2. Qualification conversion can only apply to a pointer, can not apply to a reference. For the example below, if the conversion `int` to `const int&` involves qualification conversion, the output would be `A`; however, this example results ambiguous call.
```c++
#include <iostream>
void f(int) {
std::cout << "A" << std::endl;
}
void f(const int&) {
std::cout << "B" << std::endl;
}
int main() {
f(1);
return 0;
}
```