如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
How to allocate memory for std::vector and then call constructor for some elements later?
我正在"现代化"一个(相当古老的(C++项目,并偶然发现了这部分:
旧代码为动态数组分配内存,然后根据需要稍后为元素调用构造函数。我想为所有元素调用构造函数是昂贵的,所以作者选择这样做(性能对这个项目至关重要(。旧代码如下所示(简化(:
struct my_struct {
my_struct(int x, int y, int z) { /* expensive ctor */ }
};
struct other_class {
my_struct* arr;
other_class(int n) {
arr = (my_struct*) malloc(n * sizeof(arr[0]);
}
void foo(int idx, int a, int b, int c) {
new (&arr[idx]) my_struct(a, b, c);
}
};
我将arr
更改为std::vector<my_struct>
,并使用std::reserve
来"保留"内存。代码工作正常,通过所有当前测试,但我知道这不行,因为std::reserve
不会增加该向量的大小,因此调用arr.size()
仍将返回 0。这是我的代码:
struct other_class {
std::vector<my_struct> arr;
other_class(int n) {
arr.reserve(n);
}
void foo(int idx, int a, int b, int c) {
new (&arr[idx]) my_struct(a, b, c);
}
};
如何使这段代码快速安全(假设我无法向my_struct
添加默认 ctor (?谢谢。
编辑:这是示例代码。它按预期编译和运行,没有任何警告:http://cpp.sh/8ytwf
但我知道这不行,因为 std::reserve 不会增加该向量的大小
std::reserve
确实增加了向量容量,当您只想分配内存并且稍后才推送元素时,这正是您想要的。
向量管理的基础数组的大小不等于向量size()
。size()
返回容器中的元素数,只要没有任何size() == 0
。
当你稍后推送元素时,你不需要使用放置new,但你应该使用push_back
或emplace_back
。更具体地说,这是错误的:
new (&arr[idx]) my_struct(a, b, c);
因为您正在越界访问向量(请记住:大小是元素的数量,容量可以更大,但您不能访问大于向量大小的索引(。相反:
arr.emplace_back(a,b,c);
虽然我更喜欢emplace_back
解决方案,但在这种情况下您可以使用std::optional
。这将允许您使用idx
来确定使用有效对象填充哪个元素。
struct other_class
{
std::vector<std::optional<my_struct>> arr;
other_class( int n ) : arr( n, std::nullopt )
{ }
void foo( int idx, int a, int b, int c )
{
arr.at( idx ).emplace( a, b, c );
}
};
相关文章:
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- C++:带有大括号初始化列表的函数调用表达式 - 标准是否规定在单个元素列表的微不足道的情况下忽略大括号?
- 使用并行参数向量调用元素向量的成员函数
- 调用 erase() 函数是否也会在擦除元素之前更改迭代器值?
- 如何在不迭代的情况下对数组中的每个元素调用方法
- 为什么 delete[] 不等同于 C++ 中为每个元素调用 delete?
- C++为每个元素调用任意函数
- C 如何使用数组的元素调用类
- boost::lockfree-为排队的元素调用析构函数
- 如何使用提升 lambda 对集合中的每个元素调用方法?
- 为集合中的每个元素调用具有多个参数的函数
- 对C++向量的每个元素调用函数
- 为构造的std::vector中的每个元素调用默认构造函数
- c++11:用向量的元素调用变差函数
- 对std::array中的元素调用用户定义的构造函数
- 对一个对象上的每个元组元素调用函数,不进行递归
- 当每个字符串由"new char[]"创建时,如何对"vector<string>"的元素调用"delete"?
- 作为数组元素调用函数
- std::list 的擦除成员函数是否为所有存储的元素调用析构函数?
- 对集合中的每个元素调用print的通用算法