C ++转换运算符

时间:2014-05-26 08:04:51

标签: c++

在以下代码中:

if ( cin >> x ) { /* ... */ }

标准库定义了一个运算符转换 operator void * ,它将 istream 类型转换为 void * 。但是,如果 if 测试条件,为什么标准库没有定义从 istream 类型到 bool 的转换?或者实施背后是否有任何隐含的考虑?

2 个答案:

答案 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 ... ; }

也就是说,代替boolvoid*,他们使用指向成员的指针功能,除了被转换为bool之外,这将是真正无用的。

也就是说,使用C ++ 11,该语言的设计者注意到了这个问题并设计了以下解决方案:

explicit operator bool() const
{ return ...; }

现在,只有当对象处于真正的bool上下文(ifwhile ...)时才会调用此运算符,而不是在任何随机积分操作中。