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

前端 未结 7 1732
灰色年华
灰色年华 2020-12-28 12:18

Can I make an assumption that given

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

Is the following statement is always true?

         


        
相关标签:
7条回答
  • 2020-12-28 12:25

    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
    }
    
    0 讨论(0)
  • 2020-12-28 12:31

    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*

    0 讨论(0)
  • 2020-12-28 12:35

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

    size_type size() const;

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

    bool empty() const;

    Returns: size() == 0

    However, in clause 18 of 21.3.1 basic_string constructors it 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<>.

    I think that the 100% correct statement is that

    (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

    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().

    0 讨论(0)
  • 2020-12-28 12:36

    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.

    0 讨论(0)
  • 2020-12-28 12:43

    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

    0 讨论(0)
  • 2020-12-28 12:47

    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.

    0 讨论(0)
提交回复
热议问题