【问题标题】:Const cast to non-pointer non-reference typeconst 强制转换为非指针非引用类型
【发布时间】:2020-07-15 03:34:28
【问题描述】:

来自[expr.const.cast]/3

对于两个相似的类型 T1 和 T2,类型 T1 的纯右值可能是 如果使用 const_cast 显式转换为 T2 类型, 考虑到这两种类型的 cv 分解,每个 Pi1 是 与所有 iPi2 相同。 const_cast 的结果是指 原始实体。

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

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

应该是格式正确的,因为intint 肯定是相似的类型并且在他们的简历中没有Pi -分解(因此“每个 Pi1P em>i2 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{});
}

【问题讨论】:

  • a 参数不是 prvalue,它是 lvalue,因此转换失败的原因。
  • @RemyLebeau 谢谢,请查看我编辑的问题
  • @RemyLebeau 左值可能被隐式转换为纯右值
  • 我昨天看了这个,因为有人问类类型的左值转换可能发生在哪里;如果非指针类型相似,则 T t; const_cast&lt;T&gt;(t) 将是一个示例(这将实现临时)

标签: c++ language-lawyer const-cast


【解决方案1】:

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

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

T 类型的 cv-decompositioncviPi 这样T 就是

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

其中每个 cvi 是一组 cv 限定符(6.9.3),每个 Pi 是“指向”的“指针”(11.3.1),“指向类型 Ci 的类成员的指针”(11.3.3)、“Ni 的数组”或“未知边界的数组”(11.3.4) . [...]

然后

两个类型 T1 和 T2 是相似的,如果它们具有相同的 n 的 cv 分解,使得对应的 P i 组件相同,U 表示的类型相同。

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


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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多