Почему b [2] ложно?

11
string s;
bool b[] = {s=="",  s==s.c_str(),  s.c_str()==""};

наборы

b[] = {true, true, false};

почему b[2]ложно?

Если A==Bи не A==Cдолжно ли это подразумевать B==C?

NoComprende
источник
Теперь я вижу свою ошибку, и у меня возникает чувство дежавю, поскольку я не первый раз путаю себя со сравнением указателей.
NoComprende

Ответы:

14

В этом выражении

s.c_str()==""

сравниваются два указателя (адреса). Первый - это указатель, возвращаемый, s.c_str()а второй - указатель на первый символ (завершающий нулевой символ) строкового литерала "".

Очевидно, что адреса разные (имейте в виду, что строковый литерал имеет статическую длительность хранения).

Чтобы получить ожидаемый результат, вы должны написать вместо

std::strcmp( s.c_str(), "" ) == 0

Что касается этих двух выражений

s==""

а также

s==s.c_str()

затем сравниваются строки, потому что стандартный класс std :: string имеет перегруженный оператор == для правого операнда.

Влад из Москвы
источник
Гарантирует ли стандарт, что указатели будут разными в последнем случае? Я понимаю, что они могут быть.
Джеффри
Можно только добавить, что это должен быть UB. «сравнение со строковым литералом приводит к неопределенному поведению»
Roout
@Jeffrey Это гарантия, потому что хотя бы строка пуста. :) Но в любом случае класс std :: string использует копию аргумента своего конструктора.
Влад из Москвы
1
@Roout - «UB» означает неопределенное поведение ». Это означает, что определение языка не говорит вам о поведении программы ** . Программа с неопределенным поведением не является допустимой программой C ++.« Неопределенное поведение »означает, что Есть несколько альтернатив, и стандарт не говорит вам, какой из них будет выбран. Программа действительна, и реализация может выбрать любую из альтернатив.
Пит Беккер
@PeteBecker - программа с UB - все еще действительная программа C ++ (по крайней мере, в том смысле, что она успешно компилируется и может быть запущена).
trolley813