构造函数初始化器列表中未知长度的数组
Array of unknown length in constructor initializer list
我有一个带有成员数组的类。长度是一个常数,但是直到编译时间(在我的实际代码中,对于不同的汇编目标(定义不同的常数(。数组的类型是没有默认构造函数的类。
#define CONSTANT 2
class Data {
public:
Data(int number){}
};
class DemoClass {
private:
Data _member[CONSTANT];
public:
DemoClass():
_member{
Data(0),
Data(0)
}
{
// stuff
}
};
在此示例中,我可以使用初始化器列表设置_member
。但是,如果COSNTANT
的值更改,我必须更改该初始化列表。
从理论上讲,将DemoClass
更改为具有一个默认构造函数,该默认构造函数调用其他 0
参数的构造函数将对我的情况有用,因为我总是将使用0
调用Data
构造函数。但是,我无法更改DemoClass
,因为它在外部库中。
我考虑过的一种解决方案是创建以下类:
class CustomData : public Data {
public:
CustomData() : Data(0){}
};
这有效,但似乎有些复杂。有没有更简单的方法来初始化此数组?
我在这里找到了您问题的答案。因此,在您的情况下,应像这样应用此解决方案:
#include <utility>
#include <array>
#define CONSTANT 2
class Data {
public:
Data(int number){}
};
template<typename T, size_t...Ix, typename... Args>
std::array<T, sizeof...(Ix)> repeat(std::index_sequence<Ix...>, Args &&... args) {
return {{((void)Ix, T(args...))...}};
}
template<typename T, size_t N>
class initialized_array: public std::array<T, N> {
public:
template<typename... Args>
initialized_array(Args &&... args)
: std::array<T, N>(repeat<T>(std::make_index_sequence<N>(), std::forward<Args>(args)...)) {}
};
class DemoClass {
private:
initialized_array<Data, CONSTANT> _member;
public:
DemoClass():
_member(1234)
{
// stuff
}
};
然后,您的_member
是静态分配的固定尺寸数组。但是,这种方法有点复杂,所以也许有人可以提供更清洁的解决方案。
一个简单的解决方案是使用std::vector
。显然,这确实具有引入动态分配的缺点:
std::vector<Data> _member;
DemoClass() : _member(CONSTANT, Data(0))
IT 是如果使用原始字符存储的成员(具有足够的尺寸和对齐方式(,并且可以使用放置新构建元素,则可以在没有动态分配的情况下进行相同的操作。这也是向量所做的。但是有点复杂:
class DemoClass {
private:
std::aligned_storage_t<sizeof(Data), alignof(Data)> storage[CONSTANT];
public:
DemoClass()
{
std::uninitialized_fill(begin(), end(), Data(0));
}
Data* begin() {
return std::launder(reinterpret_cast<Data*>(std::begin(storage)));
}
Data* end() {
return std::launder(reinterpret_cast<Data*>(std::end(storage)));
}
~DemoClass() {
for(Data& d : *this)
d.~Data();
}
};
您编写示例代码的方式,它并不简单,因为您已经在Data
上创建了2个构造函数。
但是,如果将Data
更改为以下(请记住:这只是为了避免对哪个构造函数的混淆 - 您没有提供完整的代码(:
class Data {
public:
Data(int number = 0){}
};
现在,您可以用空的支架来支撑优势:
_member{ }
这将确保所有成员都是初始化的。
附加我建议使用std::array<Data, CONSTANT>
代替C数组。
相关文章:
- C++未知长度字符串的数组,其行为类似于 Python 字符串列表
- C++中数组大小未知的指针转换
- 如何定义在编译时数据未知的 const 数组
- 在C++中初始化第一维大小未知的二维数组
- 在带有模板的函数中传递未知大小的 std::数组.如何更正此代码?
- 你能让数组中的项数未知吗
- 当数组大小在C++中未知时,如何在运行时将对字符串数组的引用作为函数参数传递?
- 如何将输入到具有未知数量元素的数组中?
- 获取由空格分隔的未知大小的单行输入,并将其存储到整数数组中
- 使用 ReadProcessMemory() 将未知大小的字符数组或字符串读入 wstring 中
- 未知容器、向量或数组 c++ 的大小
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 构造函数初始化器列表中未知长度的数组
- 在 c++ 中使用未知元素初始化的字符数组
- 特征:将数组映射到矩阵大小未知的矩阵
- 如何声明一个未知大小的数组,然后输入直到我想要,然后获取数组的大小
- 如何在 C++ 中将值附加到未知大小的数组中
- 如何确定未知类型数组的索引是否为空
- 使用数组和布尔值在输出未知时从输出中删除逗号
- 如何正确写入多维字符数组未知数量的值,但固定的字符堆