c++ - 我可以在初始化之前使用 std::array 成员变量中的 data() 指针吗?发出警告
问题描述
我正在使用指向存储在派生类SelfContained的 std::array 成员中的数据的指针初始化一个基类(例如Matrix<3,3> ),在执行时被警告“在此处使用字段'vdata'未初始化”所以。
该警告是有道理的,但我不确定避免它的最佳方法......代码似乎无论如何都可以工作,但我不喜欢看到警告,所以我正在尝试修复它。
我可能完全错了,但是在这里使用时似乎分配了 std:array vdata,因此即使数组未初始化, data() 指针也应该已经有效。由于我之后立即对其进行初始化,所以我很想忽略警告......但我希望有一种更“正确”的方式......
我已经迭代了几次......以前 std::array 是一个 C 风格的数组,并且抓住指向它的指针不会导致问题。
#include <iostream>
#include <array>
template<class ContainedType>
class SelfContained: public ContainedType{
public:
typedef ContainedType Type;
static constexpr size_t numel() { return Type::numel();}
typedef std::array<double, numel()> DataArray; // Data Array Type
DataArray vdata;
SelfContained(DataArray arry_in): ContainedType(vdata.data()), vdata{arry_in} {} // WARNING: Field 'vdata' is uninitialized when used here
};
template <size_t m, size_t n>
class Matrix{
public:
typedef double DoubleArray[n][m]; // Data Array Type
DoubleArray* pdata = NULL; // Pointer to data array: to be assigned on instantiation to let instance be a specified sub-array of something else.
static constexpr size_t height() {return m;}
static constexpr size_t width() {return n;}
static constexpr size_t numel() {return m*n;}
Matrix(double* p) noexcept : pdata{(DoubleArray*)p}{}
// Element reference getters (mostly for internal convenience)
template<typename ...Args>
double& data(Args... vals){
return get_data(*this, vals...);
}
template<typename ...Args>
const double& data(Args... vals) const{
return get_data(*this, vals...);
}
// Print Matrix
void print() const {
for (size_t j=0; j<height(); j++){
for(size_t k=0;k<width(); k++){
std::printf("%+15.7f ",data(j,k));
//std::printf("%+4.1f ",data(j,k));
} std::printf("\n");
} std::printf("\n");
}
private:
// Helper functions for public element-reference getters ...
// weird, but minimizes code dupication (const/non-const) by putting the guts here
template<typename InstanceType>
static auto get_data(InstanceType& instance, size_t row) -> decltype(instance.data(row)) {
assert(row >= 0 && row < instance.numel());
return (*(instance.pdata))[0][row];
}
template<typename InstanceType>
static auto get_data(InstanceType& instance, size_t row, size_t col) -> decltype(instance.data(row,col)) {
assert(col >= 0 && col < instance.width());
assert(row >= 0 && row < instance.height());
return (*(instance.pdata))[col][row];
}
};
constexpr std::array<double,9> x0 = {1,0,0,0,2,0,0,0,3};
int main(int argc, const char * argv[]) {
SelfContained<Matrix<3,3>>(x0).print();
return 0;
}
给出警告: 在此处使用字段“vdata”时未初始化
输出:
+1.0000000 +0.0000000 +0.0000000
+0.0000000 +2.0000000 +0.0000000
+0.0000000 +0.0000000 +3.0000000
非常感谢任何帮助。谢谢!
解决方案
据我所知,在初始化vdata.begin()
之前调用在vdata
技术上是 UB,即使成员函数不需要接触任何成员。
然而,另一个问题是(DoubleArray*)p
。通过重新解释的指针进行访问,就好像它指向 a 一样,DoubleArray
当它实际上并没有指向这样的对象时,它具有未定义的行为。
推荐阅读
- dataset - Tableau CRM 迁移数据集
- python - 如何在 Python 中使用 numpy 快速计算两个不同矩阵的每一行的点积
- python - 更改数据框中的列名称并将其融化
- amazon-web-services - 如何在字典列表中使用 set_fact?
- java - 在 Java 中处理多个 CompletableFuture
- .net - Team Foundation Server 2013 构建失败/在本地构建但不在服务器上
- amazon-web-services - 无法为 AWS EKS 集群创建 Fargate 配置文件
- visual-studio-code - vscode上的终端问题
- python-3.x - 使用时间戳信息批量重命名波形音频文件
- swift - iOS iCloud 文档更改通知