семантика перемещения не используется в присутствии std :: move - PullRequest
2 голосов
/ 21 ноября 2011

со следующим:

#include <iostream>
#include <fstream>
using namespace std;
int main() {
    ifstream f;
    ifstream g;
    f = std::move(g);
}

Почему вызывается ifstream::operator=(const ifstream & ) вместо ifstream::operator=(ifstream && ), хотя std::move() вызывается?

Обновление : Вообще говоря, есть ли способ заставить ссылку lvalue на ссылку rvalue?

Ответы [ 2 ]

5 голосов
/ 21 ноября 2011

Какие у вас есть доказательства того, что ifstream::operator=(const ifstream&) вызывается?Вы получаете ошибку компиляции, которая говорит, что вы вызываете этот закрытый или удаленный член?

Если ваш код вызывает ifstream::operator=(const ifstream&), и если ваша реализация претендует на C ++ 11, тогдаошибка в вашем C ++ std :: lib или в компиляторе.Когда я компилирую ваш код, вызывается ifstream::operator=(ifstream&&).И это специально.

Я вставил оператор печати в мою реализацию ifstream::operator=(ifstream&&) просто для уверенности.Когда я сделал вашу программу, распечатывает:

basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
1 голос
/ 21 ноября 2011

Стандарт

 27.9.1.8 Assign and swap [ifstream.assign]

       basic_ifstream& operator=(basic_ifstream&& rhs);

Полагаю, вы смотрите не на тот код (нигде не гарантируется, что оператор базового класса istream::operator=(istream&&) должен вызываться)?


Обновление : Вообще говоря, есть ли способ заставить ссылку lvalue на ссылку rvalue?

Да, это то, что std::moveделает:

template <class T> typename remove_reference<T>::type&& move(T&& t) noexcept;

Существует также

template <class T> typename conditional<
  !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
  const T&, T&&>::type move_if_noexcept(T& x) noexcept;

, который делает то же самое, при условии, что конструктор перемещения не являетсяровселенным.

...