Const 转换为非指针非引用类型

Const cast to non-pointer non-reference type

来自[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 Pi1 is the same as Pi2 for all i. The result of a const_­cast refers to the original entity.

似乎允许将 const 转换为非指针非引用类型。比如下面的函数

void f(int a)
{
    const_cast<int>(a);
}

应该是合式的,因为 intint 肯定是相似的类型并且没有 Pi 在他们的 cv 分解中(因此命题 "each Pi1 is the same as Pi2 for all i" 应该是真的)。​​

但是,GCC 和 Clang 都拒绝上面的代码(参见 Compiler Explorer)。错误信息是

叮当声:

<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);
      |                      ^

海湾合作委员会:

<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);
      |     ^~~~~~~~~~~~~~~~~~

我是不是遗漏了什么或者是编译器错误?

更新:这也行不通:

void f()
{
    const_cast<int>(int{});
}

在 C++17 中,类型不相似,因此引用的文本不适用。所以这个 const_cast 是不允许的,因为除非明确允许,否则不允许 const_cast

C++17 [conv.qual]/1:

A cv-decomposition of a type T is a sequence of cvi and Pi such that T is

“cv0 P0 cv1 P1 ··· cvn-1 Pn-1 cvn Ufor n > 0,

where each cvi is a set of cv-qualifiers (6.9.3), and each Pi is “pointer to” (11.3.1), “pointer to member of class Ci of type” (11.3.3), “array of Ni ”, or “array of unknown bound of” (11.3.4). [...]

然后

Two types T1 and T2 are similar if they have cv-decompositions with the same n such that corresponding Pi components are the same and the types denoted by U are the same.

要求n > 0表示必须有cv0 P0,即类型中至少有一个指针。


由于 Issue 2051,最新的 C++20 草案将 n > 0 更改为 n ≥ 0 .但不改变 const_cast 的规范。我不能说这是有意还是疏忽。

因此 C++20 可能会使您的 const_cast 表达式定义良好,编译器将不得不跟上。