我可以在初始化之前使用 std::array 成员变量中的 data() 指针吗?发出警告
Can I use the data() pointer from an std::array member variable before it is initialized? Gives warning
我正在使用指向存储在派生类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
之前调用vdata.begin()
在技术上是UB,即使成员函数不需要接触任何成员。
然而,另一个问题是(DoubleArray*)p
。通过重新解释的指针进行访问,就好像它指向DoubleArray
一样,当它实际上并不指向此类对象时,它具有未定义的行为。
这里的主要问题是不能强制在继承值之前初始化成员。
一种可能的解决方案是将必须首先初始化的数据成员移动到另一种类型,然后首先继承该类型,这将强制首先初始化这些继承的成员。 这样,vdata
在调用ContainedType
构造函数之前初始化。
这样做会使"这是定义的行为吗"的讨论毫无意义。
template<class ContainedType>
class SelfContainedMembers {
public:
typedef ContainedType Type;
typedef std::array<double, Type::numel()> DataArray; // Data Array Type
DataArray vdata;
SelfContainedMembers(DataArray arry_in): vdata{arry_in} { }
};
template<class ContainedType>
class SelfContained: private SelfContainedMembers<ContainedType>, public ContainedType {
public:
typedef ContainedType Type;
typedef SelfContainedMembers<ContainedType> Members;
static constexpr size_t numel() { return Type::numel();}
typedef typename Members::DataArray DataArray;
SelfContained(DataArray arry_in): Members{arry_in}, ContainedType{Members::vdata.data()} {};
};
(请参阅此示例并注意缺少警告。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 我可以在初始化之前使用 std::array 成员变量中的 data() 指针吗?发出警告
- 如何将 std::string 赋回作为 <char>void* 指针传递的 std::vector.data()?
- 为什么指针>数据有效,而 *double_pointer->data 不起作用?
- 从构造函数中本地声明的device_vector使用device_vector::data()方法初始化结构内部的指针是
- 通过 std::vector.data() 指向 std::vector 元素的指针指向损坏的数据
- 返回指向const data的const双指针
- 是否必须释放std::string.c_str()或std::string.data()返回的指针
- V8 - 铸造参数.Data() 返回到 void 指针
- 对cublassgem使用指向vector
::data()的指针