这大概could现在需要添加的是,C++11 添加了显式转换和上下文转换的概念。
When std::string
是设计好的,但这些都不存在。这使得类支持转换为bool
相当难以保证安全。特别是,这种转换可能(并且将会)在很多情况下发生,而您几乎不希望它发生。例如,如果我们假设std::string
转换为false
如果为空,否则true
,那么你可以使用string
本质上anywhere目的是整数或指针。
编译器不会告诉您类型不匹配,而是将字符串转换为 bool,然后将 bool 转换为整数(false -> 0,true -> 1)。
在字符串类型的许多早期尝试中,类似的事情经常发生(并且有many)委员会显然决定最好将隐式转换保持在绝对最小值(因此关于由string
是从 C 样式字符串创建字符串对象)。
为了更安全地处理 bool 转换,设计了多种方法。一个正在转换为void *
相反,这可以防止一些问题,但不能防止其他问题(这是 iostreams 使用的)。还有一个“safe bool”习语(实际上,更像是一个“safe bool”主题,其中有几种变体)。虽然这些确实改进了对允许和不允许的转换的控制,但大多数都涉及相当多的开销(典型的安全 bool 需要大约 50 行代码的基类,加上从该基类的派生等。 )
至于显式转换和上下文转换有何帮助,基本思想非常简单。您可以(从 C++11 开始)将转换函数标记为explicit
,这使得它只能在使用显式转换为目标类型的情况下使用:
struct X {
explicit operator bool() { return true; }
};
int main() {
X x;
bool b1 = static_cast<bool>(x); // compiles
bool b2 = x; // won't compile
}
上下文转换增加了一点,让转换为 bool 隐式发生,但是only在类似的事情中if
语句,因此使用具有上面转换函数的类,您将得到:
X x;
if (x) // allowed
int y = x; // would require explicit cast to compile
我想补充一点,关于“正交性”的抱怨在这里似乎完全不适用。虽然方便的,将字符串转换为布尔值并没有多大意义。如果有的话,我们应该抱怨这有多么奇怪string("0")
转换为1
(发生这种情况的语言)。