isnullorwhitespace - C++: ¿es string.empty() siempre equivalente a string== ""?
isnullorwhitespace c# (7)
¿Puedo hacer una suposición de que dado
std::string str;
... // do something to str
¿La siguiente afirmación es siempre cierta?
(str.empty() == (str == ""))
Algunas implementaciones pueden probar el carácter nulo como el primer carácter de la cadena, lo que resulta en un ligero aumento de velocidad sobre el cálculo del tamaño de la cadena.
Creo que esto no es común sin embargo.
Debería ser. El estándar ANSI / ISO establece en 21.3.3 basic_string
capacity :
size_type size() const;
Devuelve: un recuento de objetos de tipo char que se encuentran actualmente en la cadena.
bool empty() const;
Devoluciones:
size() == 0
Sin embargo, en la cláusula 18 de 21.3.1 constructores de cadena basic_string
, indica que el operador de asignación de traits::length()
utiliza traits::length()
para establecer la longitud de la secuencia controlada, por lo que podría terminar con algo extraño si está utilizando una especialización diferente. de std::basic_string<>
.
Creo que la declaración 100% correcta es que
(str.empty() == (str == std::string()))
o algo así. Si no has hecho nada extraño, entonces std::string("")
y std::string()
deberían ser equivalentes
Son lógicamente similares, pero están probando diferentes cosas. str.empty()
está comprobando si la cadena está vacía, str.empty()
que la otra está buscando la igualdad contra una cadena vacía de estilo C. Utilizaría el que sea más apropiado para lo que estás tratando de hacer. Si quiere saber si una cadena está vacía, entonces use str.empty()
.
Normalmente, sí.
Pero si alguien decide redefinir a un operador, entonces todas las apuestas están apagadas:
bool operator == (const std::string& a, const char b[])
{
return a != b; // paging www.thedailywtf.com
}
Sí, es equivalente, pero permite que el código central cambie la implementación de lo que empty () realmente significa que depende de OS / Hardware / cualquier cosa y no afecta en absoluto su código. Existe una práctica similar en Java y .NET
str.empty () nunca es más lento, pero podría ser más rápido que str == "". Esto depende de la implementación. Entonces deberías usar str.empty () por si acaso.
Esto es un poco como usar ++ i en vez de i ++ para aumentar un contador (suponiendo que no necesita el resultado del operador de incremento). Su compilador puede optimizar, pero no pierde nada con ++ i, y puede ganar algo, por lo que es mejor usar ++ i.
Además de los problemas de rendimiento, la respuesta a su pregunta es sí; Ambas expresiones son lógicamente equivalentes.
Sí (str.empty() == (str == ""))
siempre es * verdadero para std::string
. Pero recuerde que una string
puede contener caracteres ''/0''
. Entonces, aunque la expresión s == ""
puede ser falsa, s.c_str()
aún puede devolver una C-cadena vacía. Por ejemplo:
#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;
}
** salvo una sobrecarga de operator==
en el espacio de nombre global, como otros lo han mencionado *
Responder
Sí. Aquí está la implementación relevante de bits/basic_string.h
, el código para basic_string<_CharT, _Traits, _Alloc>
:
/**
* Returns true if the %string is empty. Equivalent to *this == "".
*/
bool
empty() const
{ return this->size() == 0; }
Discusión
Aunque las dos formas son equivalentes para std::string
, es posible que desee usar .empty()
porque es más general.
De hecho, JF Sebastian comenta que si cambia a usar std::wstring
lugar de std::string
, entonces ==""
ni siquiera compilará, porque no puede comparar una cadena de wchar_t
con una de char
. Esto, sin embargo, no es directamente relevante para su pregunta original, y estoy 99% seguro de que no cambiará a std::wstring
.