在我们日常使用C++的各种场景中,通过while(cin>>num),while(getline(cin,str))这种来判断输入是很常见的。那么这种istream对象到bool的转换具体是怎么实现的呢。
1.旧版实现
这里会不会是直接在istream类中直接定义bool的类型转换呢——形如operator bool (){ };
很遗憾,并没有这么简单。因为我们知道,bool型会自动类型提升为int型,所以直接定义operator bool ()之后。
cout<<2这种表达式,编译器不知道将他转换为bool(cout)<<2这种移位操作还是输出操作。
所以以前的C++标准采用了一个替代的方法,定义operator void * (){ }; 即定义转换为void*类型的指针,因为可以通过判断指针是否为nullptr来转换为bool。
但这种方法也有一定的问题,比如说允许了delete std::cout或char c = cin;这种语句的编译通过。
2.C++11的safe-bool
所以C++11引入了safe-bool,即将explicit关键字扩充到可以修饰转换类型函数——explicit operator bool() const;
使得对象只有在上下文需要判断bool条件的时候才会自动转换为bool类型。
if,while,for(§6.4 [stmt.select] p4)
binary logical operators&&and||(§5.14 [expr.log.and/or] p1for both)
the logical negation operator!(§5.3.1 [expr.unary.op] p9)
conditional operator?:(§5.14 [expr.cond] p1)
static_assert(§7 [dcl.dcl] p4)
noexcept(§15.4 [except.spec] p2)
注意,bool f=cin;不能通过编译,因为不是需要判断的情况。
参考
Why operator void*() conversion function added to the C++ stream classes?