当前位置:网站首页>本周小贴士#141:注意隐式转换到bool
本周小贴士#141:注意隐式转换到bool
2022-07-07 15:39:00 【-飞鹤-】
作为TotW#141最初发表于2018年1月19日
由Samuel Freilich创作
两种空指针检查
在解引用之前检查指针是否为空来避免崩溃和错误很重要。这可以通过两种方式完成:
if (foo) {
DoSomething(*foo);
}
if (foo != nullptr) {
DoSomething(*foo);
}
鉴于foo是一个指针,这两个条件具有相同的语义,但后面的类型检查更严格点。在C++中,许多类型都可以隐式转换为bool,当指向的类型本身转换为bool时需要额外注意。
考虑以下代码,它可能具有两个截然不同的含义:
bool* is_migrated = ...;
// 这是在检测is_migrated是否为空,或者真实意图是校验*is_migrated为真呢?
if (is_migrated) {
...
}
这份代码更清晰:
// 看起来像是对一个bool*的空指针进行检查
if (is_migrated != nullptr) {
...
}
这两种样式在 Google C++ 代码中都是可接受的。 所以当底层类型不能隐式转换为 bool 时,遵循周围代码的风格。 如果所讨论的值是像 std::unique_ptr 这样的“智能指针”,则语义和权衡是相同的。
可选值和作用域分布
可选(例如 absl::optional)值呢? 他们值得更仔细的考虑。
例如:
absl::optional<bool> b = MaybeBool();
if (b) {
... } // 当函数返回absl::optional(false)时发生了什么?
将变量声明放在 if 语句的条件中会限制变量的作用域,但该值会隐式转换为布尔值,因此可能无法明确测试哪个布尔属性。
以下代码的意图更清楚:
absl::optional<bool> b = MaybeBool();
if (b.has_value()) {
... }
请注意,实际上,上面的代码片段是等价的:absl::optional 到 bool 的转换只查看 optional 是否已满,而不是查看其内容。 读者可能会发现 optional(false) 为 true 有悖常理,但很明显 optional(false) 有一个值。 同样,当底层类型可以隐式转换为 bool 时,需要格外小心。
可选返回值的一种模式是将变量声明放在 if 语句的条件中。 这限制了变量的范围,但涉及到布尔的隐式转换:
if (absl::optional<Foo> foo = MaybeFoo()) {
DoSomething(*foo);
}
注意:在 C++17 中,if 语句可以包含初始化器,因此可以限制声明的范围,同时避免隐式转换:
if (absl::optional<Foo> foo = MaybeFoo(); foo.has_value()) {
DoSomething(*foo);
}
类布尔枚举
假设您已经采纳了技巧 #94 的建议,并决定在函数签名中使用枚举而不是 bool,以便在调用站点获得更好的可读性。 这种重构可能会在函数定义中引入隐式转换:
void ParseCommandLineFlags(
const char* usage, int* argc, char*** argv,
StripFlagsMode strip_flags_mode) {
if (strip_flags_mode) {
// 哪个值又是真呢?
...
}
}
您可以通过用显式比较替换隐式转换来获得额外的清晰度:
void ParseCommandLineFlags(
const char* usage, int* argc, char*** argv,
StripFlagsMode strip_flags_mode) {
if (strip_flags_mode == kPreserveFlags) {
...
}
}
总结
总之,注意隐匿转换为bool可能是不清楚的,因此考虑编写更显式的代码:
- 将指针类型与 nullptr 进行比较(特别是如果指向的类型可以隐式转换为 bool)。
- 使用诸如 absl::optional::has_value() 之类的布尔函数测试容器是否为空(特别是如果包含的类型可以隐式转换为 bool)。 对 if 使用可选的初始化形式来限制变量的范围(提示 #165)。 不过请记住只调用接口,不要获取 value() 或 has_value() 的地址。 testing::Optional 匹配器可以帮助测试。
- 将枚举与特定值进行比较。
更详细参考:Contextual conversions
边栏推荐
- 科普达人丨一文弄懂什么是云计算?
- Is AI more fair than people in the distribution of wealth? Research on multiplayer game from deepmind
- With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore
- LeetCode1051(C#)
- 【黄啊码】为什么我建议您选择go,而不选择php?
- 麒麟信安加入宁夏商用密码协会
- Siggraph 2022 best technical paper award comes out! Chen Baoquan team of Peking University was nominated for honorary nomination
- PLC: automatically correct the data set noise, wash the data set | ICLR 2021 spotlight
- LeetCode 1654. The minimum number of jumps to get home one question per day
- Shallow understanding Net core routing
猜你喜欢

网络攻防复习篇

mysql官网下载:Linux的mysql8.x版本(图文详解)

Mrs offline data analysis: process OBS data through Flink job

Pychart ide Download

测试用例管理工具推荐

科普达人丨一文弄懂什么是云计算?

【Seaborn】组合图表:FacetGrid、JointGrid、PairGrid

With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore

skimage学习(2)——RGB转灰度、RGB 转 HSV、直方图匹配

企业即时通讯软件是什么?它有哪些优势呢?
随机推荐
鲲鹏开发者峰会2022 | 麒麟信安携手鲲鹏共筑计算产业新生态
Notes on installing MySQL in centos7
[fan Tan] those stories that seem to be thinking of the company but are actually very selfish (I: building wheels)
LeetCode 213. Home raiding II daily question
LeetCode刷题day49
让保险更“保险”!麒麟信安一云多芯云桌面中标中国人寿, 助力金融保险信息技术创新发展
PLC:自动纠正数据集噪声,来洗洗数据集吧 | ICLR 2021 Spotlight
DNS 系列(一):为什么更新了 DNS 记录不生效?
国内首创!Todesk将RTC技术融入远程桌面,画质更清晰操作更流畅
Skimage learning (3) -- adapt the gray filter to RGB images, separate colors by immunohistochemical staining, and filter the maximum value of the region
The server is completely broken and cannot be repaired. How to use backup to restore it into a virtual machine without damage?
SlashData开发者工具榜首等你而定!!!
How to mount the original data disk without damage after the reinstallation of proxmox ve?
LeetCode 1626. The best team without contradiction
Flask build API service SQL configuration file
[source code interpretation] | source code interpretation of livelistenerbus
Sator a lancé le jeu web 3 "satorspace" et a lancé huobi
LeetCode 1477. Find two subarrays with sum as the target value and no overlap
MySQL usage notes 1
【TPM2.0原理及应用指南】 12、13、14章