Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么std::string未隐式转换为bool P>是否有一个原因,为什么在C++ +>代码> STD::String < /C>中没有隐式地转换为BoL?比如说 std::string s = "" if (s) { /* s in not empty */ }_C++_String_Casting_Boolean - Fatal编程技术网

为什么std::string未隐式转换为bool P>是否有一个原因,为什么在C++ +>代码> STD::String < /C>中没有隐式地转换为BoL?比如说 std::string s = "" if (s) { /* s in not empty */ }

为什么std::string未隐式转换为bool P>是否有一个原因,为什么在C++ +>代码> STD::String < /C>中没有隐式地转换为BoL?比如说 std::string s = "" if (s) { /* s in not empty */ },c++,string,casting,boolean,C++,String,Casting,Boolean,与其他语言(如python)一样。我认为使用empty方法很乏味。这可能是因为C++11添加了显式转换和上下文转换的概念 当设计std::string时,它们都不存在。这使得支持转换到bool的类很难保持安全。特别是,这种转换在很多情况下都可能(而且会)发生,而你几乎从未想过会发生这种情况。例如,如果我们假设std::string如果为空则转换为false,否则转换为true,那么您可以在需要整数或指针的任何位置使用字符串 编译器不会告诉您类型不匹配的情况,而是将字符串转换为bool,然后将bo

与其他语言(如python)一样。我认为使用
empty
方法很乏味。

这可能是因为C++11添加了显式转换和上下文转换的概念

当设计
std::string
时,它们都不存在。这使得支持转换到
bool
的类很难保持安全。特别是,这种转换在很多情况下都可能(而且会)发生,而你几乎从未想过会发生这种情况。例如,如果我们假设
std::string
如果为空则转换为
false
,否则转换为
true
,那么您可以在需要整数或指针的任何位置使用
字符串

编译器不会告诉您类型不匹配的情况,而是将字符串转换为bool,然后将bool转换为整数(false->0,true->1)

类似的事情在许多早期尝试字符串类型(而且有很多)时经常发生,委员会显然认为最好将隐式转换保持在绝对最小值(因此
string
支持的唯一隐式转换是从C样式的字符串创建字符串对象)

为了更安全地处理到bool的转换,设计了许多方法。一个是转换为
void*
,这可以防止一些问题,但不能防止其他问题(iostreams使用了这一功能)。还有一个“安全布尔”成语(实际上,更像是一个“安全布尔”主题,有几个变体)。虽然这些方法无疑改善了对哪些转换是允许的,哪些转换是不允许的的的控制,但大多数方法都涉及相当大的开销(一个典型的安全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
}
我要补充的是,关于“正交性”的抱怨在这里似乎并不适用。虽然很方便,但将字符串转换为布尔值并没有多大意义。如果有什么问题的话,我们应该抱怨
字符串(“0”)
转换为
1
(在发生这种情况的语言中)是多么奇怪。

提到了
操作符bool()
可能导致意外结果的一些原因

请注意,
std::string
只是
std::basic_string
的一个typedef。还有用于多字节字符的
std::wstring
。隐式转换将允许您编写:

std::string foo = "foo";
std::wstring bar = "bar";
if (foo == bar) {
  std::cout << "This will be printed, because both are true!\n";
}
if ("") { ... }
std::string foo=“foo”;
std::wstring bar=“bar”;
如果(foo==bar){

std::cout
std::string
仍然必须与C样式的字符串共存

根据定义,C样式字符串是“由第一个空字符终止并包括第一个空字符的连续字符序列”,通常通过指向其第一个字符的指针进行访问。例如
“hello,world”在大多数上下文中,
隐式转换为指向第一个字符的指针。这样的指针可以隐式转换为
bool
,如果指针非空,则生成
true
,如果指针为空,则生成
false
。(在C语言中,它没有转换为bool,但它仍然可以直接用作条件,因此效果几乎相同。)

因此,由于C++的C传统,如果您编写:

std::string foo = "foo";
std::wstring bar = "bar";
if (foo == bar) {
  std::cout << "This will be printed, because both are true!\n";
}
if ("") { ... }
空字符串已被视为
true
,在不破坏C兼容性的情况下很难更改

我建议将C风格的空字符串作为<代码>真< /COD>和C++空代码> STD::String 作为<代码> false <代码>太混淆了。


如果(!s.empty())
不是那么难(而且我觉得它更易读)。

我能找到的最接近你(和我)想要的东西是以下内容

您可以在
std::string上定义
运算符,如下所示:

bool operator!(const std::string& s)
{
    return s.empty();
}
这允许您执行以下操作:

std::string s;
if (!s)             // if |s| is empty
使用一个简单的否定,你可以:

if (!!s)            // if |s| is not empty
这有点尴尬,但问题是,你有多希望避免额外的字符?
!strcmp(…)
也很尴尬,但我们仍然使用并习惯了它,我们很多人都喜欢它,因为它比键入
strcmp(…)==0快


如果有人在C++中发现了一个方法来做<代码>(s)<代码>,请让我们知道。

因为它没有操作符<代码>布尔()/代码>,因为标准不需要一个,因为……它应该如何定义?为什么在你看来是空的假和非空的真的?它不是(也不是空向量评估为false等)。。可能是疏忽,但可能是故意忽略的,因为已经出现了大量的隐式转换错误。@deviantfan:这不是我的观点:这在许多情况下都很常见languages@RuggeroTurra但是,如果你用ASM中的字符串(跳跃等)来制作条件,C++就不象Python,JS& Co.因为地址不是0,这是C和C++起源的地方,而不是来自动态类型等。它可能是许多语言的共同特征,但是在那些字符串值应该被认为是假的,并且应该被认为是真的语言中,当然没有一个共同的约定。