c++规范是否说明如何在static_cast/const_cast链中选择用于C风格强制转换的类型?

Does the C++ specification say how types are chosen in the static_cast/const_cast chain to be used in a C-style cast?

本文关键字:cast 用于 选择 风格 类型 转换 const 说明 是否 c++ static      更新时间:2023-10-16

这个问题涉及到我在c++规范中注意到的一些东西,当时我试图回答这个关于C风格强制转换和类型转换的有趣问题。

c++规范在第5.4节中讨论了C风格的强制转换。它表示强制转换符号将按此顺序尝试以下强制转换,直到找到一个有效的强制转换:

  • const_cast
  • static_cast
  • static_castconst_cast
  • reinterpret_cast
  • reinterpret_castconst_cast

虽然我对使用static_cast后跟const_cast意味着什么有一个很好的直观想法(例如,通过const_cast<Base*>(static_cast<const Base*>(expr))const Derived*转换为Base*),但我没有看到规范中的任何措辞说明如何具体地推导static_cast/const_cast系列中使用的类型。在简单指针的情况下,这并不难,但从链接的问题中可以看出,如果在一个地方引入额外的const并在另一个地方删除,则强制转换可能会成功。

是否有任何规则来管理编译器应该如何确定在强制转换链中使用什么类型?如果有,他们在哪里?如果不是,这是语言的缺陷,还是有足够的隐式规则来唯一地确定要尝试的所有可能的强制转换?

如果没有,这是语言的缺陷,还是有足够的隐式规则来唯一地确定要尝试的所有可能的强制转换?

如果只使用const_cast构造所有可以转换为目标类型的类型,即所有的"中间类型"呢?

给定目标类型T,如果static_cast不起作用,确定所有可以添加cv限定符的位置,以便通过const_cast 1将结果类型强制转换回T。算法概要:取T的cv-decomposition ([conv.qual]/1);每个cvj都可以增广。如果T是引用,则可以增加推荐人类型的cv-限定条件。

现在将const volatile添加到所有这些位置。调用结果类型CT。尝试将static_cast表达式改为CT。如果可以,我们的转换链是const_cast<T>(static_cast<CT>( e ))

如果这不起作用,很可能没有使用static_castconst_cast进行转换(我没有深入研究过载解析的深层问题(我有,但不是为了这个问题))。但是,如果我们真的想要的话,我们可以使用暴力来重复删除const/volatile,并检查每种类型。所以理论上,不存在歧义或规格不足;如果有一些铸链,就可以确定。在实践中,该算法可以非常简单,因为我们可以从T构造的"最符合cv"的类型(肯定)是足够的。