C ++: всегда ли string.empty () эквивалентно string == ""? - PullRequest
47 голосов
/ 27 января 2009

Могу ли я сделать предположение, что с учетом

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

Следующее утверждение всегда верно?

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

Ответы [ 7 ]

52 голосов
/ 27 января 2009

Ответ

Да. Вот соответствующая реализация от 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; }

Обсуждение

Несмотря на то, что две формы эквивалентны для std::string, вы можете захотите использовать .empty(), поскольку оно более общее.

Действительно, J.F. Себастьян комментирует, что если вы переключитесь на использование std::wstring вместо std::string, =="" даже не скомпилируется, потому что вы не можете сравнить строку wchar_t с одной из char. Это, однако, не имеет прямого отношения к вашему первоначальному вопросу, и я на 99% уверен, что вы не переключитесь на std::wstring.

11 голосов
/ 27 января 2009

Так и должно быть. Стандарт ANSI / ISO гласит: 21.3.3 basic_string емкость :

size_type size() const;

Возвращает: количество похожих на символы объектов в настоящее время в строке.

bool empty() const;

Возвращает: size() == 0

Однако в пункте 18 конструкторов 21.3.1 basic_string говорится, что оператор присваивания символьного типа использует traits::length(), чтобы установить длину контролируемой последовательности, чтобы вы могли получить что-то странно, если вы используете другую специализацию std::basic_string<>.

Я думаю, что 100% правильное утверждение состоит в том, что

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

или что-то в этом роде. Если вы не сделали ничего странного, то std::string("") и std::string() должны быть эквивалентны

Они логически похожи, но они проверяют разные вещи. str.empty() проверяет, является ли строка пустой, тогда как другой проверяет равенство пустой строке в стиле C. Я бы использовал то, что больше подходит для того, что вы пытаетесь сделать. Если вы хотите узнать, пуста ли строка, используйте str.empty().

7 голосов
/ 27 января 2009

str.empty () никогда не медленнее, но может быть быстрее, чем str == "". Это зависит от реализации. Поэтому вы должны использовать str.empty () на всякий случай.

Это немного похоже на использование ++ i вместо i ++ для увеличения счетчика (при условии, что вам не нужен результат самого оператора приращения). Ваш компилятор может оптимизировать, но вы ничего не потеряете, используя ++ i, и можете что-то выиграть, поэтому вам лучше использовать ++ i.

Помимо вопросов производительности, ответ на ваш вопрос - да; оба выражения логически эквивалентны.

3 голосов
/ 28 января 2009

Да (str.empty() == (str == "")) всегда * верно для std::string. Но помните, что string может содержать '\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('\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;
}

** за исключением перегрузки operator== в глобальном пространстве имен, как уже упоминали другие *

1 голос
/ 27 января 2009

Обычно да.

Но если кто-то решит переопределить оператора, все ставки отменены:

bool operator == (const std::string& a, const char b[])
{
    return a != b; // paging www.thedailywtf.com
}
1 голос
/ 27 января 2009

Некоторые реализации могут проверять наличие нулевого символа в качестве первого символа в строке, что приводит к небольшому увеличению скорости по сравнению с вычислением размера строки.

Я считаю, что это не так часто.

0 голосов
/ 27 января 2009

Да, это эквивалентно, но позволяет основному коду изменять реализацию того, что фактически означает empty (), в зависимости от ОС / Аппаратного обеспечения / чего-либо и никак не влиять на ваш код. В Java и .NET

есть похожая практика
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...