问题描述
有没有理由为什么在c ++ std :: string
不是隐式转换为bool?例如
Is there a reason why in c++ std::string
is not implicitly converted to bool? For example
std::string s = ""
if (s) { /* s in not empty */ }
我认为使用 empty
方法很繁琐。
as in other languages (e.g. python). I think it is tedious to use the empty
method.
推荐答案
当添加了显式转换和上下文转换的概念时, std :: string
被设计,但这些都不存在。这使得支持转换 bool
的类很难保持安全。特别是,这种转换可能(并且会)发生在很多情况下,你几乎不想要它。例如,如果我们假设 std :: string
转换为 false
true ,那么你可以使用 string
本质上在任何地方一个整数或指针。
When std::string
was designed, neither of these was present though. That made classes that supported conversion to bool
fairly difficult to keep safe. In particular, that conversion could (and would) happen in lots of cases you almost never wanted it to. For example, if we assume std::string
converts to false
if empty and otherwise to true
, then you could use a string
essentially anywhere an integer or pointer was intended.
而不是告诉你类型不匹配,编译器会将字符串转换为bool,然后将bool转换为一个整数(false - > 0,true - > 1)。
Rather than telling you about the type mismatch, the compiler would convert the string to bool, and then the bool to an integer (false -> 0, true -> 1).
这样的事情经常发生,很多早期尝试字符串类型(和有很多),委员会显然决定更好地保留隐式转换绝对最小值(因此 string
支持的唯一隐式转换是从C风格字符串创建一个字符串对象)。
Things like this happened often enough with many early attempts at string types (and there were many) that the committee apparently decided it was better to keep implicit conversions to an absolute minimum (so about the only implicit conversion supported by string
is to create a string object from a C-style string).
有很多方法设计用于更安全地处理转换为bool。一个是转换为 void *
,它阻止了一些问题,但不是其他人(这是iostreams使用)。还有一个安全bool成语(实际上,更像一个安全bool主题,其中有几个变化)。虽然这些肯定改善了对将要和不允许的转换的控制,但是大多数都涉及相当大的开销(典型的安全bool需要一个大约50行代码的基类,加上从该基类派生的基类等等。 )
There were a number of methods devised for handling conversion to bool more safely. One was converting to void *
instead, which prevented some problems, but not others (this was used by iostreams). There was also a "safe bool" idiom (actually, more like a "safe bool" theme, of which there were several variations). While these certainly improved control over what conversions would and wouldn't be allowed, most of them involved a fair amount of overhead (a typical safe bool required a base class of ~50 lines of code, plus derivation from that base class, etc.)
至于显式转换和上下文转换将如何帮助,基本想法很简单。您可以(从C ++ 11开始)将转换函数标记为 explicit
,这允许它仅在使用到目标类型的显式转换时使用:
As to how explicit conversion and contextual conversion would help, the basic idea is pretty simple. You can (starting with C++11) mark a conversion function as explicit
, which allows it to be used only where an explicit cast to the target type is used:
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隐式发生,但仅在 if
语句中,因此使用具有上述转换函数的类,你会得到:
Contextual conversion adds a little to let the conversion to bool happen implicitly, but only in something like an if
statement, so using a class with the conversion function above, you'd get:
X x;
if (x) // allowed
int y = x; // would require explicit cast to compile
我补充说,关于正交性的投诉似乎不适用这里。虽然方便,将字符串转换为布尔值并不真正有意义。如果有什么,我们应该抱怨 string(0)
如何转换为 1
发生这种情况的语言)。
I'd add that complaints about "orthogonality" seem quite inapplicable here. Although convenient, converting a string to a Boolean doesn't really make a lot of sense. If anything, we should complain about how strange it is for string("0")
to convert to 1
(in languages where that happens).
这篇关于为什么std :: string不会隐式转换为bool的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!