在以下代码中:
if ( cin >> x ) { /* ... */ }
标准库定义了一个运算符转换 operator void * ,它将 istream 类型转换为 void * 。但是,如果 if 测试条件,为什么标准库没有定义从 istream 类型到 bool 的转换?或者实施背后是否有任何隐含的考虑?
答案 0 :(得分:8)
原因很简单,您不希望意外地转换为int
。例如,假设存在对bool
的隐式转换,并且您编写了
if (std::cin << x) { /* ... */ }
编译器无法捕获明显的错误(使用<<
而不是>>
),因为隐式转换将转换为int
并愉快地移动结果。这几乎肯定不是预期的。 void*
无法移位,即编译器会产生错误。
在C ++ 11之前,无法标记转换运算符explicit
。您只能将转化构造函数标记为explicit
。在C ++ 11中,流的转换运算符实际上已更改为explicit
转换为bool
,因为转换为void*
也存在一些问题。
答案 1 :(得分:3)
operator bool()
一直有点问题。主要问题是C ++中的bool
是算术运算符,因此任何实现operator bool()
的类都将自动转换为int
。
因此,以下代码是合法的,但没有意义:
cout << (2 * cin);
标准库的设计者认为操作员不太可能导致问题,同时能够转换为bool
将是operator void*
。我们的想法是,void*
不能用于任何事情。
也就是说,其他更现代的库,例如boost
,有时会使用以下习语:
typedef void *this_type::*unspecified_bool_type;
operator unspecified_bool_type() const { return ... ; }
也就是说,代替bool
或void*
,他们使用指向成员的指针功能,除了被转换为bool
之外,这将是真正无用的。
也就是说,使用C ++ 11,该语言的设计者注意到了这个问题并设计了以下解决方案:
explicit operator bool() const
{ return ...; }
现在,只有当对象处于真正的bool上下文(if
,while
...)时才会调用此运算符,而不是在任何随机积分操作中。