C++:string.empty() 总是等价于 string == "" 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/483337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:35:52  来源:igfitidea点击:

C++: is string.empty() always equivalent to string == ""?

c++string

提问by Michael

Can I make an assumption that given

我可以假设给定

std::string str;
... // do something to str

Is the following statement is always true?

以下陈述是否总是正确的?

(str.empty() == (str == ""))

回答by A. Rex

Answer

回答

Yes. Here is the relevant implementation from bits/basic_string.h, the code for basic_string<_CharT, _Traits, _Alloc>:

是的。这是来自 的相关实现bits/basic_string.h,代码为basic_string<_CharT, _Traits, _Alloc>

  /**
   *  Returns true if the %string is empty.  Equivalent to *this == "".
   */
  bool
  empty() const
  { return this->size() == 0; }

Discussion

讨论

Even though the two forms are equivalent for std::string, you maywish to use .empty()because it is more general.

尽管这两种形式 for 是等价的std::string,但您可能希望使用.empty()它,因为它更通用。

Indeed, J.F. Sebastiancomments that if you switch to using std::wstringinstead of std::string, then ==""won't even compile, because you can't compare a string of wchar_twith one of char. This, however, is not directly relevant to your original question, and I am 99% sure you will not switch to std::wstring.

事实上,JF Sebastian评论说,如果您切换到使用std::wstring而不是std::string,那么==""甚至不会编译,因为您无法将一个字符串wchar_t与其中之一进行比较char。但是,这与您的原始问题没有直接关系,我 99% 确定您不会切换到std::wstring.

回答by D.Shawley

It should be. The ANSI/ISO standard states in 21.3.3 basic_stringcapacity:

它应该是。ANSI/ISO 标准在21.3.3basic_string容量中规定

size_type size() const;

Returns:a count of char-like objects currently in the string.

bool empty() const;

Returns:size() == 0

size_type size() const;

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

bool empty() const;

返回:size() == 0

However, in clause 18 of 21.3.1 basic_stringconstructorsit states that the character-type assignment operator uses traits::length()to establish the length of the controlled sequence so you could end up with something strange if you are using a different specialization of std::basic_string<>.

但是,在21.3.1basic_string构造函数的第 18 条中,它指出字符类型赋值运算符用于traits::length()建立受控序列的长度,因此如果您使用 的不同特化,则最终可能会出现一些奇怪的情况std::basic_string<>

I think that the 100% correct statement is that

我认为 100% 正确的说法是

(str.empty() == (str == std::string()))

or something like that. If you haven't done anything strange, then std::string("")and std::string()should be equivalent

或类似的东西。如果你没有做过什么奇怪的事情,那么std::string("")andstd::string()应该是等价的

They are logically similar but they are testing for different things. str.empty()is checking if the string is empty where the other is checking for equality against a C-style empty string. I would use whichever is more appropriate for what you are trying to do. If you want to know if a string is empty, then use str.empty().

它们在逻辑上是相似的,但它们正在测试不同的东西。str.empty()正在检查字符串是否为空,而另一个正在检查是否与 C 样式的空字符串相等。我会使用更适合您尝试做的事情。如果您想知道字符串是否为空,请使用str.empty().

回答by Gorpik

str.empty() is never slower, but might be faster than str == "". This depends on implementation. So you should use str.empty() just in case.

str.empty() 从不慢,但可能比 str == "" 快。这取决于实现。所以你应该使用 str.empty() 以防万一。

This is a bit like using ++i instead of i++ to increase a counter (assuming you do not need the result of the increment operator itself). Your compiler might optimise, but you lose nothing using ++i, and might win something, so you are better off using ++i.

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

Apart from performance issues, the answer to your question is yes; both expressions are logically equivalent.

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

回答by jwfearn

Yes (str.empty() == (str == ""))is always* true for std::string. But remember that a stringcan contain '\0'characters. So even though the expression s == ""may be false, s.c_str()may still return an empty C-string. For example:

Yes(str.empty() == (str == ""))对于 始终* 为真std::string。但请记住, astring可以包含'\0'字符。因此即使表达式s == ""可能为假,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('
bool operator == (const std::string& a, const char b[])
{
    return a != b; // paging www.thedailywtf.com
}
'); 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('##代码##'); 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; }

**barring an overload of operator==in the global namespace, as others have mentioned*

**除非operator==其他人提到的全局命名空间中的重载*

回答by Jesse Dearing

Some implementations might test for the null character as the first character in the string resulting in a slight speed increase over calculating the size of the string.

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

I believe that this is not common however.

我相信这并不常见。

回答by John Carter

Normally, yes.

通常,是的。

But if someone decides to redefine an operator then all bets are off:

但是,如果有人决定重新定义运算符,那么所有赌注都将取消:

##代码##

回答by Ray Booysen

Yes it is equivalent but allows the core code to change the implementation of what empty() actually means depending on OS/Hardware/anything and not affect your code at all. There is similiar practice in Java and .NET

是的,它是等效的,但允许核心代码根据操作系统/硬件/任何东西来更改 empty() 实际含义的实现,并且根本不影响您的代码。在 Java 和 .NET 中有类似的做法