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?

Respuestas a la pregunta(6)

Su respuesta a la pregunta