Разрешено ли изменять результат std :: string :: op []? - PullRequest
23 голосов
/ 14 октября 2011

Рассмотрим следующее из C ++ 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[] или нет? И это не довольно двусмысленная формулировка?

Ответы [ 2 ]

12 голосов
/ 14 октября 2011

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

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

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

4 голосов
/ 06 августа 2013

В n3690 (черновик C ++ 14) формулировка была изменена на:

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

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

...