Действительность итераторов и потоки - PullRequest
1 голос
/ 25 января 2012

Предположим, что в основном потоке программы на C ++ 11 я создаю std::set, заполняю его элементами и извлекаю из него итератор it. После этого из другого потока я начинаю модифицировать набор таким образом, чтобы элементы могли только добавляться к нему, но не стираться.

Гарантируется ли действительность it также во время изменения набора, или я должен считать it недействительным, когда набор модифицируется операциями вставки из другого потока?

1 Ответ

4 голосов
/ 25 января 2012

Из раздела 23.2.1 [container.requirements.general]:

Если не указано иное (явно или путем определения функции в терминах других функций), вызов функции-члена контейнера или передача контейнера в качествеАргумент библиотечной функции не должен делать недействительными итераторы или изменять значения объектов в этом контейнере.

Для ассоциативных контейнеров, таких как std::set, в разделе 23.2.4 ([associative.reqmts]) говорится:

Элементы insert и emplace не должны влиять на действительность итераторов и ссылок на контейнер, а члены erase должны делать недействительными только итераторы и ссылки на стертые элементы.

Таким образом, ваши итераторы останутся действительными после вставки дополнительных элементов.

Однако безопасность потоков - это совершенно другая тема.

Раздел 17.6.5.9 ([res.on.data.races])предусматривает, что

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

Поскольку это приводит к чтению контейнера во время его обновления, не обязательно безопасно использовать итератор std::set при вставке в коллекциюиз другого потока .Ваша реализация может обеспечить более сильную гарантию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...