为了看看std::move是如何工作的,我尝试模仿(很好地复制了原始代码)std::move函数;但令我惊讶的是,它不像std::move那样工作。我的move函数最终调用了copy ctor而不是move ctor。
#include <iostream>
#define My_version
template <class _Ty>
struct remove_reference {
using type = _Ty;
using _Const_thru_ref_type = const _Ty;
};
template <class _Ty>
using remove_reference_t = typename remove_reference<_Ty>::type;
#ifdef My_version
template<typename T> // in namespace std
typename remove_reference<T>::type&&
mymove(T&& param)
{
std::cout << "My_version\n";
using ReturnType = typename remove_reference<T>::type&&;
return static_cast<ReturnType>(param);
}
#else
template <class _Ty>
constexpr remove_reference_t<_Ty>&& mymove(_Ty&& _Arg) noexcept { // forward _Arg as movable
return static_cast<remove_reference_t<_Ty>&&>(_Arg);
}
#endif // My_version
class simple
{
public:
simple(int kk) :k(kk) {}
simple(simple&& rhs) noexcept
{
std::cout << "move is called \n";
k = rhs.k;
rhs.k = -1; //moved
}
simple(const simple& rhs)noexcept
{
std::cout << "copy is called \n";
k = rhs.k*10;
}
int k;
};
int main()
{
{
std::cout << "===============================\nmymove\n===============================\n";
simple a(42);
simple b = mymove(a);
std::cout << " after move\nmovedObj.k " << b.k << " originalObj.k " << a.k << "\n";
}
{
std::cout << "\n\n===============================\nstd::move\n===============================\n";
simple a(42);
simple b = std::move(a);
std::cout << "after move\nmovedObj.k " << b.k << " originalObj.k " << a.k << "\n";
}
return 0;
}
我尝试了std::move函数的精确副本和略有不同的样式函数,可以在这里看到由#ifdef分隔。与std::move不同,两者都调用复制ctor。
std::move导致move构造函数,为什么我的move函数会导致copy。
===============================
mymove
===============================
copy is called
after move
movedObj.k 420 originalObj.k 42
===============================
std::move
===============================
move is called
after move
movedObj.k 42 originalObj.k -1
1条答案
按热度按时间3pvhb19x1#
正如- HolyBlackCat所建议的那样,为remove_reference添加两个引用专门化解决了这个问题。