*std::prev(std::end(<associative-container>)) -> UB?
От: _niko_ Россия  
Дата: 23.12.19 13:35
Оценка:
На сколько корректна следующая запись:
std::set<int> associative_container{ 1, 2, 3, 4 };
int back_value{ *std::prev(std::end(associative_container)) };

Стандарт дает какие то гарантии, что декремент end-итератора будет указывать на последний элемент ассоциативного контейнера?
Или это все же UB?
Re: *std::prev(std::end(<associative-container>)) -> UB?
От: rg45 СССР  
Дата: 23.12.19 13:45
Оценка: 4 (1)
Здравствуйте, _niko_, Вы писали:

__>На сколько корректна следующая запись:

__>
__>std::set<int> associative_container{ 1, 2, 3, 4 };
__>int back_value{ *std::prev(std::end(associative_container)) };
__>

__>Стандарт дает какие то гарантии, что декремент end-итератора будет указывать на последний элемент ассоциативного контейнера?
__>Или это все же UB?

https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator

Это не стандарт, конечно, но доверять этому ресурсу можно, имхо:

Notes
The begin iterator is not decrementable and the behavior is undefined if --container.begin() is evaluated. A bidirectional iterator does not have to be dereferenceable to be decrementable (in particular, the end iterator is not dereferenceable but is decrementable)


Само собой, для пустого контейнера, декремент от end приведет к UB, ибо end равен begin.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 23.12.2019 13:58 rg45 . Предыдущая версия . Еще …
Отредактировано 23.12.2019 13:49 rg45 . Предыдущая версия .
Re: *std::prev(std::end(<associative-container>)) -> UB?
От: Vamp Россия  
Дата: 23.12.19 15:25
Оценка: +1
Здравствуйте, _niko_, Вы писали:

__>Или это все же UB?

Не UB. Но вообще если вопрос не абстрактный, то специально для этих целей придуман rbegin.
Да здравствует мыло душистое и веревка пушистая.
Re: *std::prev(std::end(<associative-container>)) -> UB?
От: Шахтер Интернет  
Дата: 23.12.19 15:36
Оценка:
Здравствуйте, _niko_, Вы писали:

__>На сколько корректна следующая запись:

__>
__>std::set<int> associative_container{ 1, 2, 3, 4 };
__>int back_value{ *std::prev(std::end(associative_container)) };
__>

__>Стандарт дает какие то гарантии, что декремент end-итератора будет указывать на последний элемент ассоциативного контейнера?

... если контейнер не пуст.

Даёт. Итераторы ассоциативного контейнера -- это bidirectional итераторы. Дальше смотри свойства этого класса итераторов.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: *std::prev(std::end(<associative-container>)) -> UB?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 23.12.19 16:59
Оценка:
Здравствуйте, _niko_, Вы писали:

__>На сколько корректна следующая запись:

Корректна
__>
__>std::set<int> associative_container{ 1, 2, 3, 4 };
__>int back_value{ *std::prev(std::end(associative_container)) };
__>

лучше это используй std::rbegin(v), но учти, он может быть std::rend()
__>Стандарт дает какие то гарантии, что декремент end-итератора будет указывать на последний элемент ассоциативного контейнера?
если декремент применим, то всё бует норм.
__>Или это все же UB?
нет
Sic luceat lux!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.