如何在C++中实现移动功能?
How to implement the move function in C++?
我想了解 C++ 中 move 函数的内部结构。
为此,我打算自己实现名为 move2 的移动函数。
这是我的实现,带有用于跟踪内存分配的打印。
#include <iostream>
#include <vector>
using namespace std;
void * operator new(size_t size) {
cout << "New operator overloading " << endl;
void * p = malloc(size);
return p;
}
void operator delete(void * p) {
cout << "Delete operator overloading " << endl;
free(p);
}
template<typename T>
T move2(T& input) {
cout << "Running move2 " << endl;
return (T&&)input;
}
int main()
{
{
cout<<"Test#1"<<endl;
vector<int> temp1(10,4);
vector<int> temp2 = temp1;
}
{
cout<<"Test#2"<<endl;
vector<int> temp3(10,4);
vector<int> temp4 = (vector<int>&&)(temp3);
}
{
cout<<"Test#3"<<endl;
vector<int> temp5(10,4);
vector<int> temp6 = move(temp5);
}
{
cout<<"Test#4"<<endl;
vector<int> temp7(10,4);
vector<int> temp8 = move2(temp7);
}
return 0;
}
这是输出
Test#1
New operator overloading
New operator overloading
Delete operator overloading
Delete operator overloading
Test#2
New operator overloading
Delete operator overloading
Test#3
New operator overloading
Delete operator overloading
Test#4
New operator overloading
Running move2
Delete operator overloading
我想知道我的 move2 实现是否正确,我可以在生产中使用它吗?
更新:
我找到了移动的 GCC 实现
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
std::move()
接收 forwarding reference,returns 接收 T&&
右值引用。你的 move2()
两者都没有。它接收一个左值引用,并且 returns 按值 T
。
你的代码“有效”是因为复制省略避免了当你的函数 returns 按值创建一个新对象时创建临时对象,从而允许 temp8
直接用你的类型转换构造引用 input
,从而转移其数据的所有权。不过,这并不是因为 move2()
实施得当。
试试这个:
template<typename T>
std::remove_reference_t<T>&& move2(T&& input) {
...
return static_cast<std::remove_reference_t<T>&&>(input);
}
我想了解 C++ 中 move 函数的内部结构。 为此,我打算自己实现名为 move2 的移动函数。
这是我的实现,带有用于跟踪内存分配的打印。
#include <iostream>
#include <vector>
using namespace std;
void * operator new(size_t size) {
cout << "New operator overloading " << endl;
void * p = malloc(size);
return p;
}
void operator delete(void * p) {
cout << "Delete operator overloading " << endl;
free(p);
}
template<typename T>
T move2(T& input) {
cout << "Running move2 " << endl;
return (T&&)input;
}
int main()
{
{
cout<<"Test#1"<<endl;
vector<int> temp1(10,4);
vector<int> temp2 = temp1;
}
{
cout<<"Test#2"<<endl;
vector<int> temp3(10,4);
vector<int> temp4 = (vector<int>&&)(temp3);
}
{
cout<<"Test#3"<<endl;
vector<int> temp5(10,4);
vector<int> temp6 = move(temp5);
}
{
cout<<"Test#4"<<endl;
vector<int> temp7(10,4);
vector<int> temp8 = move2(temp7);
}
return 0;
}
这是输出
Test#1
New operator overloading
New operator overloading
Delete operator overloading
Delete operator overloading
Test#2
New operator overloading
Delete operator overloading
Test#3
New operator overloading
Delete operator overloading
Test#4
New operator overloading
Running move2
Delete operator overloading
我想知道我的 move2 实现是否正确,我可以在生产中使用它吗?
更新:
我找到了移动的 GCC 实现
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
std::move()
接收 forwarding reference,returns 接收 T&&
右值引用。你的 move2()
两者都没有。它接收一个左值引用,并且 returns 按值 T
。
你的代码“有效”是因为复制省略避免了当你的函数 returns 按值创建一个新对象时创建临时对象,从而允许 temp8
直接用你的类型转换构造引用 input
,从而转移其数据的所有权。不过,这并不是因为 move2()
实施得当。
试试这个:
template<typename T>
std::remove_reference_t<T>&& move2(T&& input) {
...
return static_cast<std::remove_reference_t<T>&&>(input);
}