Подтвердить что ты не робот

Является ли законным изменять результат std::string:: op []?

Рассмотрим из С++ 11 следующее:

[C++11: 21.4.5]: basic_string доступ к элементу             [String.access]

const_reference operator[](size_type pos) const;
reference       operator[](size_type pos);

1   Требуется: pos <= size().

2   Возвращает: *(begin() + pos), если pos < size(), в противном случае ссылка на объект типа T со значением charT(); ссылочное значение не должно быть изменено.

3   Броски: ничего.

4   Сложность: постоянное время.

Это означает:

  • Исходное значение в случае pos == size() не должно быть изменено или
  • В любом случае ссылочное значение, возвращаемое op[], не может быть изменено даже для перегрузки не const.

Второй сценарий кажется совершенно нелепым, но я думаю, что это наиболее выражает формулировка.

Можем ли мы изменить то, что получаем из std::string::op[], или нет? И это не довольно неоднозначная формулировка?

4b9b3361

Ответ 1

Цитата означает, что вы не можете изменить возврат operator[]( size() ), даже если значение определено корректно. То есть вы не должны изменять терминатор NUL в строке даже через неконстантную перегрузку.

Это в основном ваш первый вариант: т.е. pos >= size(), но из-за требования pos <= size() единственным возможным значением для этого условия является pos == size().

Фактическое английское описание предложения может быть неоднозначным (по крайней мере для меня), но Приложение C и, в частности, C.2.11, касается изменений в семантике в библиотеке строк, и об этом изменении нет, что нарушит код пользователя. В С++ 03 "ссылочное значение не должно быть изменено" бит отсутствует и нет двусмысленности. Отсутствие упоминания в C.2.11 не является нормативным, но может использоваться как намек на то, что, когда они написали стандарт, не было намерения изменять это конкретное поведение.

Ответ 2

В n3690 (черновик С++ 14) текст был изменен на:

Возвращает: *(begin() + pos), если pos < size(). В противном случае возвращается ссылка на объект типа charT со значением charT(), где изменение объекта приводит к поведению undefined.

Я считаю, что это устраняет английскую двусмысленность и ясно указывает на намерение оригинального двусмысленного прохода С++ 11.