У меня есть функция, которая потенциально перемещает общий аргумент, но через его членов. Какой из этих вариантов более правильный:
Это кажется более естественным, но странным, потому что аргумент потенциально перемещается дважды [a], что странно, поскольку объект может стать недействительным.
template<class T> void fun(T&& t){ myhead_ = std::forward<T>(t).head_; myrest_ = std::forward<T>(t).rest_; }
Это не может быть неправильным, но может ничего не перемещать.
template<class T> void fun(T&& t){ myhead_ = std::forward<decltype(t.head_)>(t.head_); myrest_ = std::forward<decltype(t.rest_)>(t.rest_); }
Это кажется правильным, но слишком много кода.
template<class T> void fun(T& t){ myhead_ = t.head_; myrest_ = t.rest_; } template<class T> void fun(T&& t){ myhead_ = std::move(t.head_); myrest_ = std::move(t.rest_); }
[a] Это утверждение неверно, как указал @Angew, оно только выглядит так, как будто оно было перемещено дважды. std::forward
(как и std::move
) на самом деле ничего не двигает. В лучшем случае элемент перемещается (последующей операцией decltype(myhead)::operator=
, но это как раз и является целью).