如何优雅地初始化std::atomic数组?
How do I elegantly initialize an array of std::atomic?
假设我有一个类,其成员数组为std::atomic
s,其中数组的大小是通过计算来确定的(也就是说,它可能会根据程序中其他地方的常量而改变):
class Foo {
static constexpr size_t kArraySize = ComputeArraySize();
std::atomic<size_t> atomics_[kArraySize];
};
确保原子都初始化为最优雅的方式是什么零?我能做得比循环数组在Foo
的构造函数和更好吗显式存储零?std::array
的答案不同吗?
通常我会在这里使用大括号初始化式,但是派生出的长度(其中(可能很长)使它变得困难。
注意,我不能假设Foo
的实例具有静态存储持续时间。
好的,我相信我已经解决了这个问题。这两个都会初始化所有的原子归零:
std::atomic<size_t> plain_array[kArraySize] = {};
std::array<std::atomic<size_t>, kArraySize> std_array = {};
逻辑如下:
[dcl.init。
[数组。cons]/1规定
std::array
也是一个集合[dcl.init。Aggr]/7表示如果初始化器的元素较少列表中先有成员在聚合,再剩余成员从一个空的初始化列表初始化。在这种情况下,是所有成员。
[dcl.init。/3从一个空列表为类定义了列表初始化使用默认构造函数(如
std::atomic
)来引起value-initialization . (dcl 。/7表示没有用户提供的构造函数的类zero-initialized。假设
std::array<T>
包含T
的数组,std::atomic<size_t>
的零表示是我们所期望的,
std::atomic
有一个用户提供的构造函数,只是没有用户提供的default构造函数(后者是显式默认的)。所以它在技术上不符合最后一点的条件。但是看起来在标准中是否有错误,并在最近被修正草稿。 来晚了一点。我发现自己在尝试创建原子向量时也遇到了同样的问题,正如其他用户所报告的那样,std::原子不能很好地与std::数组或std::vector库配合使用。对此,我的解决方案是创建一个包含底层原子的包装器模板类和一个创建第一个包装器类的堆分配数组的模板类。下面是我的解决方案:
#include <atomic>
template <typename T>
class Atomic_PNet
{
public:
std::atomic<T> member;
Atomic_PNet::Atomic_PNet()
{
};
Atomic_PNet::~Atomic_PNet()
{
printf("Atom deletedn");
}
};
template <typename T>
class Atomic_Vector
{
private:
int vector_size;
Atomic_PNet<T> * Atom;
public:
Atomic_Vector::Atomic_Vector()
{
vector_size = 0;
};
Atomic_Vector::~Atomic_Vector()
{
delete[] Atom;
};
void resize(int size, T value)
{
if (vector_size == 0)
{
vector_size = size;
Atom = new Atomic_PNet<T>[size];
}
for (int i =0; i < size; i++)
{
Atom[i].member = value;
}
};
std::atomic<T> &Atomic_Vector::operator[](int index)
{
Atomic_PNet<T> * atm;
atm = (Atom) + index;
return (atm->member);
};
};
这里有几件事需要注意,我不打算在第一次调整大小之后改变这个类的数组大小(这是实际发生堆分配的时候)。虽然我可以编写方法在任何其他地方调整数组的大小,但我选择不这样做,因为类本身不是原子的,只有其包装的成员是原子的(这可能导致未定义的行为)。幸运的是,我的用例不要求我在任何其他点调整大小。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '