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

2020-02-17 21:44发布

Can I make an assumption that given

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

Is the following statement is always true?

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

标签: c++ string
7条回答
家丑人穷心不美
2楼-- · 2020-02-17 22:22

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

#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;
}

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

查看更多
戒情不戒烟
3楼-- · 2020-02-17 22:32

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.

查看更多
别忘想泡老子
4楼-- · 2020-02-17 22:32

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

查看更多
狗以群分
5楼-- · 2020-02-17 22:36

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

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.

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

查看更多
\"骚年 ilove
6楼-- · 2020-02-17 22:36

Normally, yes.

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

bool operator == (const std::string& a, const char b[])
{
    return a != b; // paging www.thedailywtf.com
}
查看更多
女痞
7楼-- · 2020-02-17 22:38

Answer

Yes. Here is the relevant implementation from bits/basic_string.h, the code for 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 may wish to use .empty() because it is more general.

Indeed, J.F. Sebastian comments that if you switch to using std::wstring instead of std::string, then =="" won't even compile, because you can't compare a string of wchar_t with 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.

查看更多
登录 后发表回答