简体   繁体   中英

Const cast to non-pointer non-reference type

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 that T is

“cv 0 P 0 cv 1 P 1 ··· cv n-1 P n-1 cv n Ufor 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM