2012-02-08 4 views
22

Я знаю std::queue::pop()void. По двум причинам: безопасностьМожет queue :: pop вернуть значение сейчас?

  1. исключение: что-то может бросить после удаления элемента
  2. , чтобы иметь возможность return the value by reference

Fine.

Теперь, если я правильно понимаю новую семантику перемещения C++ 11, вторая больше не является допустимым аргументом.

Итак, единственное, что предотвращает std::queue, чтобы иметь функцию pop-like, возвращающую значение, заключается в возможности броска конструктора перемещения?

Мне тяжело думать о ситуациях, когда такой конструктор движений будет бросать. Кто знает пример?

Я думаю, то же самое касается std::stack::pop(), std::vector::pop_front(), std::vector::pop_back(), std::deque::pop_front(), std::deque::pop_back(), std::list::pop_front(), std::list::pop_back() и что нет.

+0

Это действительно два вопроса. Пример для метательного конструктора перемещения и возвращаемого 'pop'. – pmr

+0

Мне нужен пример метательного конструктора перемещения, чтобы понять, почему у нас не может появиться «pop». –

+3

Что относительно типов, у которых нет конструктора перемещения вообще? – jalf

ответ

5

Используя умные методы SFINAE это действительно было бы возможно иметь атомные ноны метания pop_and_move() только для типов данных, которые не реализуют не бросание движения или нет метания копии.

Существует даже конструкция noexcept(), чтобы увидеть, может ли что-то бросить.

Одна из новых концепций в C++ 11, в частности, которая расширяет SFINAE, заключается в том, что если тело не компилируется, функция не существует. Таким образом, можно реализовать на основе noexcept().

Я бы сказал, что для обеспечения обратной совместимости функции потребуется новое имя, что позволяет ей сосуществовать с существующей функциональностью вызова их по отдельности, не разбивая контейнеры типов, у которых нет семантики, чтобы это разрешить.

+0

Не могли бы вы рассказать о расширении SFINAE в C++ 11 (стандартная ссылка будет приятной)? Я вообще об этом не слышал и хотел бы прочитать выше. – Grizzly

+1

Это упоминалось Александреску в его разговоре о вариативных шаблонах на конференции Going Native. В рамках принципа «отказ от замены не является ошибкой», если тело не будет компилироваться, это также считается сменой замещения (таким образом, игнорировать эту специализацию). С помощью noexcept() возможно уже создать функцию, которая будет использовать перемещение, если она доступна, а не метать, а затем использовать копию как второй вариант, если она доступна и не бросается, и в противном случае не скомпилировать. – CashCow

+1

Звучит многообещающе! Этот ответ не самый прямой ответ на мои вопросы, но на самом деле это то, что я искал, не зная. –

6

Существует не так много случаев, когда std::move() может использовать стандартную библиотеку, но есть случаи. Например, если в контейнере используется генератор с установленными состояниями, его дочерние элементы также используют этот распределитель, но он не будет перенесен в результат: это скорее получит построенную по умолчанию версию распределителя (если я правильно удалю). Учитывая, что распределители являются состояниями, это означает, что объект нельзя перемещать, и, таким образом, конструкция перехода сбой исключается. Почему у этого типа есть конструктор перемещения? Ну, потому что он может быть создан с помощью нестационарного распределителя, и в этом случае перемещение не будет выбрасываться. Кроме того, как только мы переходим к пользовательским классам, мы понятия не имеем, при каких условиях их перемещение может бросить.

+0

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

1

Другая проблема заключается в том, что не каждому классу действительно выгодно перемещаться, т. Е. Они могут иметь только копию ctor.

struct DontLikeMoves{ 
    // some data, whatever... 
    DontLikeMoves(DontLikeMoves const& other){ 
    // might throw, who knows! 
    // and this will even get called for rvalues 
    } 
}; 
Смежные вопросы