C++中从double/int/string自动转换为bool

3

我是一名Java程序员,想学习一些C++知识。这里有一小段代码片段,我认为它能够工作,是因为有隐式转换的存在,但我想知道规范的哪个部分涉及了这个问题以及其他隐式转换规则,是否有文档/链接/网站介绍隐式转换规则?

#include <vector>
#include <iostream>
#include <iterator>

int main(void) {
  using namespace std;
  vector<bool> a;
  a.push_back("asdf");
  a.push_back("");  
  a.push_back(12);  
  a.push_back(0.0);  
  copy(a.begin(), a.end(), ostream_iterator<bool>(cout, "\n"));
  return 0;
}

/*
output:

1
1
1
0
*/

TIA,
sasuke


2
关于你的代码片段,最重要的要知道的是vector<bool>vector的一个特化版本,在几个方面表现不同(虽然这些方面都与你的问题无关,但是我认为你应该知道)。在使用它时要小心。 - Björn Pollex
1
在C++中不建议使用vector<bool>。 - DumbCoder
2
@Constantinius,你把它搞反了。 - Chad
1
@sasuke:这是一篇讨论vector<bool>问题的文章:http://www.gotw.ca/gotw/050.htm。 - Fred Larson
1
@sasuke: 如果您想要一个类似于BOOL的动态数组,那么可以使用vector<char>;或者如果您想要包含实际的bool值的序列容器,则可以使用deque<bool>;又或者,如果您想要最小化内存使用,并且不介意它不是一个真正的容器,那么可以使用vector<bool>boost::dynamic_bitset(接口更丰富)或者std::bitset(如果大小是固定的)。 - Mike Seymour
显示剩余14条评论
2个回答

9
指针、整数和布尔值都是“整型”,前三者都是指针或整数,由于它们都是非零值,所以它们转换为布尔值“true”。类型为“double”的第四个值转换为零整型值,因此为“false”。
不能表示为整数值(如无限大和NaN)的双精度浮点数的转换未定义。
详见4.9节,以及4.12节中的“布尔转换”:
算术、未作用域枚举、指针或成员指针类型的prvalue可以转换为bool类型的prvalue。零值、空指针值或空成员指针值转换为false;任何其他值转换为true。
您的“0.0”是零值的算术类型。
也许您不熟悉C++中的字符串字面值:“”表示数组char [1] {0},这个数组(一个元素)衰减为其第一个元素的指针,这必然是一个非空指针。同样,“asdf”表示一个数组char [5] {'a','s','d','f',0},同样地,它衰减为(非空)指向其第一个元素的指针。字符的实际值完全不重要。

哇,非常复杂。你在上一段提到的所有内容(指指针衰减、""作为char[1]等)都是规范的一部分吗?(特别是char[1]部分) - sasuke
2
@sasuke:这并不复杂,只是如果你想要做出准确的陈述,可能会有点啰嗦。大多数真正的C++程序员都有一个心理快捷方式,所以当他们看到字符串字面值时,他们会立即想到“指针”,但有时准确性很重要。 - Kerrek SB
@LuchianGrigore:double是一种算术类型,而0.0是一个零值的双精度浮点数...所以你有一个零值的算术类型。有什么不清楚的吗? - Kerrek SB
那部分很清楚,我不理解“不能表示为整数值的双精度转换(如无穷大和NaN)是未定义的”。 - Luchian Grigore
1
@LuchianGrigore 非零值被转换为真。 - curiousguy
显示剩余6条评论

2

所有基本类型都可以隐式转换为bool。任何不是0的值都是TRUE,而0则是FALSE

对于用户定义的类型,如果使用指针,任何不是NULL的值都会被视为TRUE,否则为FALSE

如果使用对象实例而不是指针,则需要声明operator bool()

class A
{
public:
   operator bool() {return false;};
};

//....

A a;
if ( a ) //compiles because of the operator
   //...;

你能详细说明一下最后一部分吗?你所说的“对象实例”是什么意思?是指像Person p;而不是Person* p;这样的东西吗? - sasuke
@sasuke 没错。我写了一个小例子。 - Luchian Grigore
3
请注意,operator bool()会导致许多其他问题 - 这促使C++03中出现了安全bool习惯用法。然而,显然这已经过时了 - Björn Pollex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接