Inconsistencia entre std :: string y literales de cadena
He descubierto una inquietante inconsistencia entrestd::string
y literales de cadena en C ++ 0x:
#include <iostream>
#include <string>
int main()
{
int i = 0;
for (auto e : "hello")
++i;
std::cout << "Number of elements: " << i << '\n';
i = 0;
for (auto e : std::string("hello"))
++i;
std::cout << "Number of elements: " << i << '\n';
return 0;
}
La salida es:
Number of elements: 6
Number of elements: 5
Entiendo la mecánica de por qué sucede esto: el literal de cadena es realmente una matriz de caracteres que incluye el carácter nulo, y cuando el rango basado en bucles llama astd::end()
en la matriz de caracteres, obtiene un puntero más allá del final de la matriz; Como el carácter nulo es parte de la matriz, obtiene un puntero más allá del carácter nulo.
Sin embargo, creo que esto es muy indeseable: seguramentestd::string
y los literales de cadena deberían comportarse igual cuando se trata de propiedades tan básicas como su longitud?
¿Hay alguna forma de resolver esta inconsistencia? Por ejemplo, puedestd::begin()
ystd::end()
se sobrecargue para las matrices de caracteres para que el rango que delimiten no incluya el carácter nulo de terminación? Si es así, ¿por qué no se hizo esto?
EDITA: Para justificar un poco más mi indignación ante aquellos que han dicho que solo estoy sufriendo las consecuencias de usar cadenas de estilo C que son una "característica heredada", considere un código como el siguiente:
template <typename Range>
void f(Range&& r)
{
for (auto e : r)
{
...
}
}
¿Esperaríasf("hello")
yf(std::string("hello"))
para hacer algo diferente?