Can I make an assumption that given
std::string str;
... // do something to str
Is the following statement is always true?
(str.empty() == (str == ""))
Can I make an assumption that given
std::string str;
... // do something to str
Is the following statement is always true?
(str.empty() == (str == ""))
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; }
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
.
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
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.
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
}
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.
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()
.
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