Является ли законным изменять результат 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[]
, или нет? И это не довольно неоднозначная формулировка?
Ответы
Ответ 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.