From [expr.const.cast]/3 :
For two similar types T1 and T2, a prvalue of type T1 may be explicitly converted to the type T2 using a const_cast if, considering the cv-decompositions of both types, each P i 1 is the same as P i 2 for all i . The result of a const_cast refers to the original entity.
It seems that const cast to non-pointer non-reference type is allowed. For example, the following function
void f(int a)
{
const_cast<int>(a);
}
should be well-formed, since int
and int
are certainly similar types and have no P i in their cv-decompositions (thus the proposition that "each P i 1 is the same as P i 2 for all i " should be true).
However, both GCC and Clang reject the code above (see Compiler Explorer ). The error messages are
Clang:
<source>: In function 'void f(int)':
<source>:3:22: error: invalid use of const_cast with type 'int', which is not a pointer, reference, nor a pointer-to-data-member type
3 | const_cast<int>(a);
| ^
GCC:
<source>: In function 'void f(int)':
<source>:3:5: error: invalid use of 'const_cast' with type 'int', which is not a pointer, reference, nor a pointer-to-data-member type
3 | const_cast<int>(a);
| ^~~~~~~~~~~~~~~~~~
Am I missing something or is it a compiler bug?
UPDATE : this doesn't work, either:
void f()
{
const_cast<int>(int{});
}
In C++17 the types are not similar so the quoted text doesn't apply. And so this const_cast
is not allowed because no const_cast
is allowed unless explicitly permitted.
C++17 [conv.qual]/1:
A cv-decomposition of a type
T
is a sequence of cv i and P i such thatT
is“cv 0 P 0 cv 1 P 1 ··· cv n-1 P n-1 cv n
U
” for n > 0 ,where each cv i is a set of cv-qualifiers (6.9.3), and each P i is “pointer to” (11.3.1), “pointer to member of class C i of type” (11.3.3), “array of N i ”, or “array of unknown bound of” (11.3.4). [...]
and then
Two types T 1 and T 2 are similar if they have cv-decompositions with the same n such that corresponding P i components are the same and the types denoted by
U
are the same.
The requirement n > 0 means that there must be cv 0 P 0 , ie at least one pointer in the type.
The latest C++20 draft changes n > 0 to n ≥ 0 , as a result of Issue 2051 . But makes no change to the specification of const_cast
. I couldn't say whether this is intentional or an oversight.
So it may be that C++20 will make your const_cast
expressions well-defined, and compilers will have to catch up.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.