C++依赖于隐式转换到条件中的bool?

moa*_*ala 6 c++ coding-style implicit-cast

我在编码标准表中找到了以下规则:

在条件中不要依赖隐式转换为bool.

if(ptr)//错了

if(ptr!= NULL)//好的

这个规则有多合理/有用?

编译代码多少重载?

Mar*_*som 11

从最严格的意义上讲,你可以依靠隐式转换来加油.向后兼容C需要它.

因此,它成为代码可读性的问题.代码标准的目的通常是强制执行代码样式的相同性,无论您是否同意样式.如果你正在看别人的标准,并想知道你是否应该将它纳入你自己的标准,那就继续讨论吧 - 但如果这是你公司的长期规则,那么就要学会忍受它.


Mat*_*ley 5

在大多数情况下,它并不可怕,但如果您输入的确切含义,它可以更具可读性.


Mic*_*fik 5

如果您想要使用具有隐式转换的类,那么该规则会将您置于绑定中bool,例如std::istream.此代码一次从文件读取一个单词,直到达到EOF:

std::ifstream file("foo.txt");
std::string word;

while (file >> word)
{
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

流提取操作符返回对文件流的引用,该引用被隐式转换bool为指示流是否仍处于良好状态.当您到达文件末尾时,测试失败.您的编码标准使您无法使用此常见结构.

对于指针类型,这不是什么大问题.编译器可能会为隐式转换bool和显式测试生成大致相同的代码NULL.这是一个品味问题 - 在绝对意义上,任何人都不是"更好".编码标准只是试图强制执行一致的风格.

考虑到这一点,在处理内置类型(指针,整数等)时,您应该完全遵循编码标准.如果你遇到与上述类似的情况,并且有一个合法转换的类bool,我会向你的队友提出这个问题.

  • 遵循以下规则仍然可以使用此功能:`while(static_cast <bool>(file >> word))`.此时,样式指南作者可能想要重新编写规则:"不要依赖于条件中指针到bool的*default*隐式转换",这可能是基于给定示例首先打算的.或者他可能希望要求`static_cast`在那里,以提醒读​​者转换发生.您无需使用隐式转换即可使用转化. (3认同)
  • @onebyone:我看一下原始代码,我认为"这会读取文件中的单词",因为我知道标准库(就像任何C++程序员一样;该结构是惯用的).我看看你的代码,我认为你试图强迫它做一些它不想做的事情,这让我很害怕.如果我在现实生活中看到你的代码,我可能花10分钟试图验证它不是一个主要的bug,并且一旦确信它没有被破坏,用Kristo的版本替换它. (3认同)
  • 应该注意的是,对于诸如您所展示的结构是否是一个好主意,存在一些争论。在重载运算符后面隐藏非类型转换功能属于“巧妙技巧”的范畴,但它真的让事情更容易阅读吗?或者在您了解图书馆中的技巧之前,它实际上会使它们更难阅读吗?与输入和输出流上的 &gt;&gt; 和 &lt;&lt; 运算符类似 - 为什么在这种特殊情况下按位运算执行 i/o?在你知道诀窍之前,它是完全不可读的。 (2认同)

lor*_*eto 5

我想为这个问题添加历史观点。

\n\n

ANSI C(又名 C89/C90)是 C 的第一个正式规范。与K&R C一起,您可能会注意到一些特殊的东西\xe2\x80\x94,没有布尔值的概念。控制流语句对表达式进行操作,其流程是根据表达式的计算结果是否为0来定义的。缺少布尔类型是 C 的最大疏忽之一。直到 C99,C 才获得了该类型,并为、和in_Bool定义了宏(注意它们仍然是整数)。同样,C++ 最初也没有布尔类型,在C++98中通过以下方式获得它booltruefalsestdbool.hbool.

\n\n

这就是为什么存在到布尔值的隐式转换的原因。在我看来,继续依赖它是糟糕的设计\xe2\x80\x94布尔值的添加是有原因的。true应始终 equal true,并且将所有非零值隐式转换为 true 并不令人满意。

\n\n

NULL也只是一个等于 0 的宏,因此具体而言,对于 C++11 中的指针,您应该使用它nullptr来确定指针是否为空。

\n\n
if(ptr != nullptr)\n{\n    // Do something with ptr.\n}\n
Run Code Online (Sandbox Code Playgroud)\n