c++ - 在使用对象初始化内部移动构造函数后,无法在转发引用中分配 nullptr
问题描述
我正在尝试习惯移动构造函数,并且在其中一个教程中被告知,在使用转发引用复制内容后初始化对 nullptr 的原始引用始终是一个好习惯。
#include <iostream>
#include <vector>
using namespace std;
template<typename T>
class Matrix{
std::vector<std::vector<T>> data;
public :
Matrix(const std::vector<std::vector<T>>& vector2D){ //Copy constructor for deep copy
// Put some error handling to check the validity of vector2D
std::cout<<"Copy Constructor Called ...\n";
__uint32_t numRow = vector2D.size();
__uint32_t numColumn = vector2D[0].size();
data.resize(numRow,std::vector<T>(numColumn));
for(auto row = 0u;row < numRow; ++row){
for(auto column = 0u; column < numColumn; ++column){
data[row][column] = vector2D[row][column];
}
}
}
Matrix(std::vector<std::vector<T>>&& vector2D){ //Move constructor for shallow copy
// Put some error handling to check the validity of vector2D
std::cout<<"Move Constructor Called ...\n";
data = vector2D;
//vector2D = nullptr; // we should assign the original reference to null in my knowledge
}
void displayVector(){
__uint32_t numRow = data.size();
__uint32_t numColumn = data[0].size();
for(auto row = 0u;row < numRow; ++row){
for(auto column = 0u; column < numColumn; ++column){
std::cout<<data[row][column]<<"\t";
}std::cout<<std::endl;
}
}
Matrix operator+ (const Matrix& rhs){
// Have to complete
return data;
}
Matrix operator* (const Matrix& rhs){
// Have to complete
return data;
}
};
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
//Matrix<int> m1(std::vector<std::vector<int>>{{1,2},{3,4}});
Matrix<int> m1({{1,2},{3,4}});
m1.displayVector();
std::vector<std::vector<int>> myVector{{5,6},{7,8}};
Matrix<int> m2(myVector);
m2.displayVector();
return 0;
}
但是,当我试图将 nullptr 放入 move 构造函数中的 vector2D 时,编译器抱怨说
没有已知的参数 1 从 std::nullptr_t 到 std::vector 的 std::initializer_list 的转换。
有哪些可能正确的方法来进行这种初始化。
解决方案
这里有两件事:
Matrix(std::vector<std::vector<T>>&& vector2D){ //Move constructor for shallow copy
// Put some error handling to check the validity of vector2D
std::cout<<"Move Constructor Called ...\n";
data = vector2D;
//vector2D = nullptr; // we should assign the original reference to null in my knowledge
}
1)您应该移动接收到的向量,以调用向量移动赋值运算符:
data = std::move(vector2D);
2)无需手动将向量设置为nullptr,它的状态已经正确设置。您从中移动的向量处于“未知但有效的状态”,因此您可以使用它做任何不假设前提条件的事情(重新分配、检查大小、检查空虚等,但是您不能期望它会里面有有效值)。正如另一个答案提到的,您还应该直接初始化数据,而不是在构造函数体中进行,所以最终构造函数应该以这种方式实现:
Matrix(std::vector<std::vector<T>>&& vector2D) : data(std::move(vector2D)) {}
推荐阅读
- youtube - YouTube API:区分 Premiered 和 Livestream
- javascript - 在Javascript中重新排序对象中的值数组
- c# - 建立连接到数据库的基于规则的系统
- swift - Firebase - 获取随机数据
- r - 在 R 中的循环中移动时处理来自同一用户的数据两次
- c++ - 针对 Win10 SDK 构建时 TYPE_ALIGNMENT(LARGE_INTEGER) 不正确
- oauth-2.0 - 捷径 OAuth/OIDC 的风险?
- java - TestNG 数据提供者将对象二维数组转换为 Hashtable - 抛出 MethodMatcherException
- python - Python beautifulsoup - 如何获取项目,稍后在浏览器中加载
- html - 如何在屏幕底部定位元素?