C++ C++;:string.empty()始终等于string="&引用;?

C++ C++;:string.empty()始终等于string="&引用;?,c++,string,C++,String,我可以假设 std::string str; ... // do something to str 以下陈述是否总是正确的 (str.empty() == (str == "")) 答复 对。以下是来自bits/basic\u string.h的相关实现,basic\u string: 讨论 尽管这两种形式对于std::string是等效的,但您可能希望使用.empty(),因为它更通用 事实上,如果您切换到使用std::wstring而不是std::string,则==“”甚至不会编译,因

我可以假设

std::string str;
... // do something to str
以下陈述是否总是正确的

(str.empty() == (str == ""))
答复 对。以下是来自
bits/basic\u string.h
的相关实现,
basic\u string

讨论 尽管这两种形式对于
std::string
是等效的,但您可能希望使用
.empty()
,因为它更通用


事实上,如果您切换到使用
std::wstring
而不是
std::string
,则
==“”
甚至不会编译,因为您无法将
wchar\u t
的字符串与
char
中的一个进行比较。但是,这与您最初的问题没有直接关系,我99%确定您不会切换到
std::wstring

是的,它是等效的,但允许核心代码根据操作系统/硬件/任何内容更改empty()实际含义的实现,而不会影响您的代码。Java和.NET中也有类似的实践

一些实现可能会测试空字符作为字符串中的第一个字符,从而导致计算字符串大小的速度略有提高

但我相信这并不常见。

正常情况下,是的

但如果有人决定重新定义一个操作符,那么所有的赌注都没有了:

bool operator == (const std::string& a, const char b[])
{
    return a != b; // paging www.thedailywtf.com
}
str.empty()从不慢,但可能比str==“”快。这取决于执行情况。所以您应该使用str.empty()以防万一

这有点像使用++i而不是i++来增加计数器(假设您不需要递增运算符本身的结果)。您的编译器可能会进行优化,但您在使用++i时不会丢失任何东西,并且可能会赢得一些东西,因此您最好使用++i


除了性能问题,您的问题的答案是肯定的;这两个表达式在逻辑上是等价的。

应该是。ANSI/ISO标准规定:

size\u type size()常量

返回:字符串中当前类字符对象的计数

bool empty()常量

返回:
size()==0

但是,在第18条中,字符类型赋值运算符使用
traits::length()
来确定受控序列的长度,因此如果使用不同的
std::basic_string
专门化,则可能会出现奇怪的结果

我认为100%正确的说法是

(str.empty() == (str == std::string()))
或者类似的。如果您没有做任何奇怪的事情,那么
std::string(“”
std::string()
应该是等效的

它们在逻辑上是相似的,但它们在测试不同的东西
str.empty()。我会用更适合你的方法。如果您想知道字符串是否为空,请使用
str.empty()

(str.empty()==(str==“”))
对于
std::string
始终为*true。但是请记住,
字符串
可以包含
'\0'
字符。因此,即使表达式
s==”
可能为false,
s.c_str()
仍可能返回空的c字符串。例如:

#include <string>
#include <iostream>
using namespace std;

void test( const string & s ) {
    bool bempty = s.empty();
    bool beq = std::operator==(s, ""); // avoid global namespace operator==
    const char * res = (bempty == beq ) ? "PASS" : "FAIL";
    const char * isempty = bempty ? "    empty " : "NOT empty ";
    const char * iseq = beq ? "    == \"\"" : "NOT == \"\"";
    cout << res << " size=" << s.size();
    cout << " c_str=\"" << s.c_str() << "\" ";
    cout << isempty << iseq << endl;
}

int main() {
    string s;          test(s); // PASS size=0 c_str=""     empty     == ""
    s.push_back('\0'); test(s); // PASS size=1 c_str="" NOT empty NOT == ""
    s.push_back('x');  test(s); // PASS size=2 c_str="" NOT empty NOT == ""
    s.push_back('\0'); test(s); // PASS size=3 c_str="" NOT empty NOT == ""
    s.push_back('y');  test(s); // PASS size=4 c_str="" NOT empty NOT == ""
    return 0;
}
#包括
#包括
使用名称空间std;
无效测试(常量字符串和s){
bool bempty=s.empty();
bool beq=std::operator==(s,“”;//避免使用全局命名空间运算符==
const char*res=(bempty==beq)?“通过”:“失败”;
const char*isempty=beempty?“空”:“不空”;
常量字符*iseq=beq?”==\“\”:“非==\”;

我希望它永远不会发生,因为C++字符串声称能够存储任何字符,包括可能的空字符。同意A. Rex。siz()应该是O(1),即无论如何存储。如果使用“=”C风格字符串,A. Rex。,它在第一个\0处停止比较。因此优化实际上是非常有效的。由于A.Rex的NUL点检查只能在
const char*
参数上进行;您仍然需要检查字符串本身是否为空,因此您必须添加仅测试empty.str.empty()的工作更一般。如果有一天你决定使用
std::wstring str
,那么
str.empty()
会起作用,但
str==“”
甚至不会编译。有人可以很容易地更改empty()事实上,如果这个运算符在全局上被定义,它将比改变整个STL要容易得多。我不知道它是否会重写在STD::String对象中定义的操作符。但是,我的观点是C++允许你用ReDeF来拍摄你的整个脚。对运营商的批评很糟糕,因此回答上述问题不可避免地依赖于警告。我实际上给了这个a+1(部分是为了提到Dailywtf.com!)。我甚至看到有人用操作符>@xtofl定义了一个操作符<作为优先级类型:@xtofl:对于最初的问题,答案是明确的“是”。此外,empty()可能比==”更有效.这个答案对我来说似乎非常特定于编译器/供应商reason@A.雷克斯:这意味着他的答案是应该被投票的,而不是你的。)在C++中,相信你的编译器或实现来说明语言应该如何表达是一个错误。所有可以告诉你的是你的实现方式,而不是磨刀。她认为1)正确,2)必要。不要太确定是否不切换到std::wstring。你永远不知道公司总部何时会想开设日本分支机构。
#include <string>
#include <iostream>
using namespace std;

void test( const string & s ) {
    bool bempty = s.empty();
    bool beq = std::operator==(s, ""); // avoid global namespace operator==
    const char * res = (bempty == beq ) ? "PASS" : "FAIL";
    const char * isempty = bempty ? "    empty " : "NOT empty ";
    const char * iseq = beq ? "    == \"\"" : "NOT == \"\"";
    cout << res << " size=" << s.size();
    cout << " c_str=\"" << s.c_str() << "\" ";
    cout << isempty << iseq << endl;
}

int main() {
    string s;          test(s); // PASS size=0 c_str=""     empty     == ""
    s.push_back('\0'); test(s); // PASS size=1 c_str="" NOT empty NOT == ""
    s.push_back('x');  test(s); // PASS size=2 c_str="" NOT empty NOT == ""
    s.push_back('\0'); test(s); // PASS size=3 c_str="" NOT empty NOT == ""
    s.push_back('y');  test(s); // PASS size=4 c_str="" NOT empty NOT == ""
    return 0;
}