2016-05-31 13 views
-3

Когда я запускаю следующий код:Почему операторы стандартной библиотеки C++ принимают значения rvalues?

std::string myString = "I'm a string."; 
const std::string::iterator &myIterator = ++myString.begin(); 
char c = *myIterator; 
std::cout << c << std::endl; 

я получаю ошибку сегментации (компиляции с оптимизацией O3). Я предполагаю, что это связано с тем, что оператор ++ возвращает std::string::iterator &, а не std::string::iterator, и поэтому мы получаем ссылку на временный. Есть ли причина, почему это не реализовано, чтобы вызвать ошибку компиляции? I.e., почему подпись не является следующей?

std::string::iterator &std::string::iterator::operator++() &; 

Или еще лучше, почему не требуют спецификаций следующих подписей, чтобы мы могли справиться rvalues ​​без проблем?

std::string::iterator &std::string::iterator::operator++() &; 
std::string::iterator std::string::iterator::operator++() &&; 
+4

[Невозможно воспроизвести] (https://ideone.com/I9Z8De). Вы уверены, что это из-за этих строк? На стороне примечания, даже если '++' возвращает ссылку, 'myIterator' не является ссылкой, поэтому он скопирует значение – Rakete1111

+3

. Это работает нормально. Можете ли вы отправить полный код? – Sumeet

+0

Да, вы правы. Я изменил этот пример, и теперь он должен потерпеть крах. –

ответ

0

код Вы разместили выглядит законным мне: std::string::iterator myIterator = ++myString.begin();копии опорной итератор в myIterator так нет оборванных ссылок на временных.

Мои психические силы отладки сказать мне, что ваш фактический код имеет один из двух проблем:

  • ваша строка фактически пуста, даже если вы думаете, что есть текст в нем. В этом случае ++begin() недействителен.
  • Вы мутируете строку после, вы получаете копию итератора таким образом, чтобы аннулировать итератор.
+0

Мое психическое предсказание состоит в том, что пример кода должен был быть «std :: string :: iterator & myIterator = ++ myString.begin();», в этом случае на самом деле происходит зависание Справка. –

+0

Хороший звонок (хотя у меня также был 'const' изначально). Я все еще не уверен, почему это должно успешно скомпилировать. –

0

@ Замечания M.M являются проницательными. В частности, мое второе предложение ограничило бы возможности библиотек при реализации итераторов, так как итераторы не должны увеличиваться как rvalues ​​(ссылка: http://en.cppreference.com/w/cpp/iterator/next), и фактически std :: string :: iterator может быть реализована как char *, который не увеличивается в качестве значения r.

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

 Смежные вопросы

  • Нет связанных вопросов^_^