переместить семантику STD :: переместить, как его использовать - PullRequest
3 голосов
/ 03 апреля 2011
#include <type_traits>

template<class T>
typename std::remove_reference<T>::type&& move(T&& v)
{
    return v;
}

void main()
{
    int a;
    move(a);
}

Почему этот код не компилируется?

ошибка C2440: «возврат»: невозможно преобразовать «int» в «int &&»

Ответы [ 2 ]

6 голосов
/ 03 апреля 2011

v является lvalue в операторе возврата (именованные ссылки rvalue являются lvalues, из соображений безопасности), но тип возврата move является ссылкой rvalue (T равно int&, но вы удаляете ссылка, поэтому вы создаете тип int && в типе возврата).

Вам нужно сначала static_cast от v до remove_reference<T>::type &&, чтобы создать неназванную ссылку rvalue, когда вы хотите ее вернуть.

Я не уверен, какова ваша цель. Либо вы хотите использовать std::move (как вы говорите в заголовке), либо вы хотите узнать, как это будет реализовано (как показывает код, который вы показываете). Нет смысла пытаться узнать, как работает std::move, не зная основных правил C ++. Я рекомендую вам взглянуть на наш C ++ Books List . После того, как вы хорошо разберетесь в C ++, вы можете узнать, как работает std::move.

4 голосов
/ 03 апреля 2011

Это прямо из проекта стандарта C ++ 0x (§20.2.3 / 6):

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

Возвращает :static_cast<typename remove_reference<T>::type&&>(t).

Следовательно, если вы измените реализацию move на следующую, она будет работать просто отлично:

template<class T>
typename std::remove_reference<T>::type&& move(T&& v)
{
    return static_cast<typename std::remove_reference<T>::type&&>(v);
}
...