В ответе на вопрос о std::stack::pop()
Я утверждал что причина pop
не возвращает значение, из соображения безопасности исключения (что происходит, если конструктор копии бросает).
@Konrad прокомментировал, что теперь с семантикой перемещения это больше не релевантно. Действительно ли это верно?
AFAIK, переместитесь, конструкторы могут throw
, но возможно с noexcept
это может все еще быть достигнуто.
Для бонусных очков, что могут предоставить гарантии потокобезопасности эта операция?
Конечно, не каждый тип поддерживает перемещение а C ++ 0x даже позволяет бросать конструкторы перемещения. Пока построение объекта из rvalue может вызывать выбросы, оно не может быть безопасным в отношении исключений. Однако семантика перемещения позволяет вам иметь много типов, которые нельзя построить с учетом источника rvalue.
Условная поддержка этого может быть сделана с помощью SFINAE. Но даже без такой условной функции-члена ничто не мешает вам написать:
auto stack = ...;
auto elem = std::move_if_noexcept(stack.back());
stack.pop_back();
, что дает сильную гарантию исключения, даже если ваш конструктор перемещения не дает строгой гарантии.
Что касается бонусного вопроса, то это не обеспечит потокобезопасности. Рассмотрим в качестве примера, что большинство реализаций std::vector
имеют три элемента данных (указатель на начало памяти, указатель на один за конец используемых данных, указатель на один за конец выделенной памяти). Семантика перемещения позволяет вам перемещать содержимое вектора без необходимости перераспределения и копирования значений, но это не имеет никакого отношения к безопасности потока. Вам придется использовать потокобезопасные конструкции, чтобы сделать структуру потокобезопасной (поскольку перемещение никоим образом не подразумевает атомарность)