Несоответствие между std :: string и строковыми литералами

Я обнаружил тревожное несоответствие между std :: string и строковыми литералами в 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;
}

Результат:

Number of elements: 6
Number of elements: 5

Я понимаю, почему это происходит: строковый литерал на самом деле представляет собой массив символов, который включает нулевой символ, и когда цикл for на основе диапазона вызывает std :: end () для символа массивон получает указатель за концом массива; поскольку нулевой символ является частью массива, он получает указатель за нулевым символом.

Однако я думаю, что это очень нежелательно: конечно std :: string и строковые литералы должны вести себя одинаково когда дело доходит до таких основных свойств, как их длина?

Есть ли способ разрешить это несоответствие? Например, можно ли перегрузить std :: begin () и std :: end () для символьных массивов, чтобы ограничиваемый ими диапазон не включал завершающий нулевой символ? Если да, то почему этого не было сделано?

РЕДАКТИРОВАТЬ : Чтобы немного больше оправдать мое возмущение тем, кто сказал, что я просто страдаю от последствий использования строк в стиле C, которые являются «устаревшей функцией» рассмотрите следующий код:

template <typename Range>
void f(Range&& r)
{
    for (auto e : r)
    {
        ...
    }
}

Ожидаете ли вы, что f ("hello") и f (std :: string ("hello")) сделают что-то другое?

38
задан HC4 - reinstate Monica 19 July 2011 в 04:27
поделиться