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?
这个问题涉及到我在c++规范中注意到的一些东西,当时我试图回答这个关于C风格强制转换和类型转换的有趣问题。
c++规范在第5.4节中讨论了C风格的强制转换。它表示强制转换符号将按此顺序尝试以下强制转换,直到找到一个有效的强制转换:
-
const_cast
-
static_cast
-
static_cast
→const_cast
-
reinterpret_cast
-
reinterpret_cast
接const_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_cast
和const_cast
进行转换(我没有深入研究过载解析的深层问题(我有,但不是为了这个问题))。但是,如果我们真的想要的话,我们可以使用暴力来重复删除const
/volatile
,并检查每种类型。所以理论上,不存在歧义或规格不足;如果有一些铸链,就可以确定。在实践中,该算法可以非常简单,因为我们可以从T
构造的"最符合cv"的类型(肯定)是足够的。
- 1d 智能指针不适用于语法 (*)++
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 用于访问容器<T>数据成员的正确 API
- 如何理解C++标准N3337中的expr.const.cast子句8
- 重载操作程序时出错>>用于类中的字符串 memebr
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++中的cin.ignore()函数不适用于整个流
- 没有用于初始化C++中的变量模板的匹配构造函数
- 用于C++中带有数组和指针的循环
- 为什么它不适用于Visual 2019的原因
- 使用在用于SFINAE的void_t中具有参数的方法
- C++Cast运算符过载
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 重载==不适用于二进制树
- Insert函数不适用于2 if语句C++
- 用于矢量处理的多个线程
- 使外部项目可用于find_package CMake
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 为什么模数运算符不适用于该代码
- 并行用于C++17中数组索引范围内的循环