Подтвердить что ты не робот

С++: string.empty() всегда эквивалентно строке == ""?

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

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

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

(str.empty() == (str == ""))
4b9b3361

Ответ 1

Ответ

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

Ответ 2

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

size_type size() const;

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

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

Ответ 3

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

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

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

Ответ 4

Да (str.empty() == (str == "")) всегда * true для std::string. Но помните, что a 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== в глобальном пространстве имен, как отмечали другие *

Ответ 5

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

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

Ответ 6

Обычно да.

Но если кто-то решит переопределить оператора, тогда все ставки не будут:

bool operator == (const std::string& a, const char b[])
{
    return a != b; // paging www.thedailywtf.com
}

Ответ 7

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