专栏首页C++核心准则原文翻译C++核心准则ES.49:如果必须进行类型转换,使用命名转换

C++核心准则ES.49:如果必须进行类型转换,使用命名转换

ES.49: If you must use a cast, use a named cast

ES.49:如果必须进行类型转换,使用命名转换

Reason(原因)

Readability. Error avoidance. Named casts are more specific than a C-style or functional cast, allowing the compiler to catch some errors.

可读性。避免错误。命名转换比C风格转换或函数形式转换更明确,允许编译器捕捉更多错误。

The named casts are:

命名转换包括:

  • static_cast
  • 静态转换
  • const_cast
  • 常量转换
  • reinterpret_cast
  • 重新解释转换
  • dynamic_cast
  • 动态转换
  • std::move // move(x) is an rvalue reference to x
  • 移动//move(x)是x的右值引用
  • std::forward // forward<T>(x) is an rvalue or an lvalue reference to x depending on T
  • 值性转递//根据T的类型,forward<T>(x)是左值或右值引用
  • gsl::narrow_cast // narrow_cast<T>(x) is static_cast<T>(x)
  • 窄化转换//narrow_cast<T>(x)就是static_cast<T>(x)
  • gsl::narrow // narrow<T>(x) is static_cast<T>(x) if static_cast<T>(x) == x or it throws narrowing_error
  • 窄化转换(抛出异常)//如果static_cast<T>(x) == x,narrow<T>(x) 就是 static_cast<T>(x),否则抛出异常
Example(示例)
class B { /* ... */ };
class D { /* ... */ };

template<typename D> D* upcast(B* pb)
{
    D* pd0 = pb;                        // error: no implicit conversion from B* to D*
    D* pd1 = (D*)pb;                    // legal, but what is done?
    D* pd2 = static_cast<D*>(pb);       // error: D is not derived from B
    D* pd3 = reinterpret_cast<D*>(pb);  // OK: on your head be it!
    D* pd4 = dynamic_cast<D*>(pb);      // OK: return nullptr
    // ...
}

The example was synthesized from real-world bugs where D used to be derived from B, but someone refactored the hierarchy. The C-style cast is dangerous because it can do any kind of conversion, depriving us of any protection from mistakes (now or in the future).

示例是从实际代码中收集的的错误集合,这段代码的前提是D过去继承于B,但有人重构了继承关系。C风格转换的危险性来自它可以是任何类型的转换,这抹杀了任何防错保护的可能性(无论是现在还是未来)。

Note(注意)

When converting between types with no information loss (e.g. from float to double or from int32 to int64), brace initialization may be used instead.

如果希望在类型之间进行无损转换(例如从float到double,或者从int32到int64),可以考虑转而使用大括号初始化。

double d {some_float};
int64_t i {some_int32};

This makes it clear that the type conversion was intended and also prevents conversions between types that might result in loss of precision. (It is a compilation error to try to initialize a float from a double in this fashion, for example.)

这种方式一方面明确了类型转换的意图,另一方面可以防止转换时损失精度。(例如,在如代码所示的情况下,如果使用double值初始化float变量,会发生编译错误)

Note(注意)

reinterpret_cast can be essential, but the essential uses (e.g., turning a machine address into pointer) are not type safe:

reinterpret_cast是必不可少的,但是这种必要的用法(例如,将机器地址转换为指针)不是类型安全的。

auto p = reinterpret_cast<Device_register>(0x800);  // inherently dangerous
Enforcement(实施建议)
  • Flag C-style and functional casts.
  • 对C风格和函数形式转换进行提醒
  • The type profile bans reinterpret_cast.
  • 类型规则群组禁止reinterpret_cast.
  • The type profile warns when using static_cast between arithmetic types.
  • 类型规则群组对在算数类型之间进行转换时使用static_cast的情况进行警告。

译者注:

C风格转换:b = int(a);

函数形式转换:b=int(a);

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es49-if-you-must-use-a-cast-use-a-named-cast

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C++核心准则C.146:如果无法避免在继承层次中移动,使用dynamic_cast

    Use of the other casts can violate type safety and cause the program to access a...

    面向对象思考
  • C++核心准则T.68:在模板中使用{}代替()以避免歧义

    T.68: Use {} rather than () within templates to avoid ambiguities

    面向对象思考
  • C++核心准则E.17:不要试图在所有函数中捕捉所有异常

    E.17: Don't try to catch every exception in every function

    面向对象思考
  • 深入理解Java虚拟机(JVM) --- 垃圾收集算法(中)

    由于方法区中存放生命周期较长的类信息、常量、静态变量. 因此方法区就像堆的老年代,每次GC只有少量垃圾被清除.

    JavaEdge
  • 【每周三面】2019前端面试系列——JS面试题

    可以判断出\'string\',\'number\',\'boolean\',\'undefined\',\'symbol\' 但判断 typeof(null)...

    趣学程序-shaofeer
  • 随着RPA的发展,人类将越来越多地退居二线

    机器人过程自动化(RPA)行业在过去一年中激增,一些领先的参与者 – 如UiPath,Automation Anywhere和Blue Prism – 增长速度...

    RPA小葵
  • 随着RPA的发展,人类将越来越多地退居二线

    机器人过程自动化(RPA)行业在过去一年中激增,一些领先的参与者 – 如UiPath,Automation Anywhere和Blue Prism – 增长速度...

    RPA机器人流程自动化
  • (四)-对象内存的分配策略1 对象优先在Eden区中分配2 大对象直接进入老年代3 生命周期较长的对象进入老年代4 对象年龄的动态判定5 "分配担保"策略详解

    JavaEdge
  • 疯狂Java笔记之Java的内存与回收

    对于JVM的垃圾回收机制来说,是否回收一个对象的标准在于:是否还有引用变量引用改对象?只要有引用变量引用对象,垃圾回收机制就不会回收它。

    HelloJack
  • 用于控制变速驱动器的高度集成iMOTION™产品系列

    通过集成所需的硬件和软件来实现对永磁同步电机(PMSM)的无传感器控制,它可以最低的系统成本,来完成最高能源效益的家电电机系统。 什么是iMOTION? ...

    机器人网

扫码关注云+社区

领取腾讯云代金券