向量复制构造函数C++:它必须是线性时间吗
vector copy constructor C++ : does it have to be linear time?
我有一个包含STL映射类型对象的向量,我做vector.push_back(some map)
。
不幸的是,这会调用映射副本构造函数,并浪费大量时间。我知道我可以通过保留一个指向映射的(智能)指针向量来解决这个问题,但这让我想知道——我读到STL无论如何都会将其数据保存在堆上,而不是堆栈上——那么为什么复制ctor不是O(1)
时间,只需复制指针?
如果在将副本推回向量后不再需要原始映射,请写入:
some_vector.push_back(std::move(some_map));
如果您还没有C++11编译器,请添加一个空映射,然后将其与原始映射进行交换:
some_vector.resize(some_vector.size() + 1);
some_vector.back().swap(some_map);
要直接回答您的问题:要做到这一点,必须从某种写时复制机制开始——当您将某个东西放入向量中时,它必须是原始文件的副本(或者至少表现得像一个)。例如,如果我将地图推到向量上,然后从原始地图中删除一个项目,那么该项目应该仍然存在于推到向量的地图副本中。
然后,它必须跟踪所有指针,并确保指针对象(在本例中为映射)保持有效,直到所有指针本身都被销毁。这样做当然是可能的。例如,相当多的语言提供垃圾收集主要是出于这个原因。其中大多数都会改变事物的语义,因此当/如果你(例如)创建一个地图向量时,将地图放入向量中具有引用语义——也就是说,当你修改原始地图时,应该会改变你放入其他集合的任何"副本"。
正如您所观察到的,如果您真的愿意,您可以在C++中执行以上任何/所有操作。现在它不存在的原因是,大多数C++标准库都是围绕值语义而不是引用语义构建的。不管怎样,两者都是(国际海事组织)一种完全有效和合理的方法——有些语言采用其中一种,另一些则采用另一种。两者都可以很好地工作,但值语义恰好是在C++中做出的选择。
如果要复制指针,请创建指向map
的指针的vector
。你可以做到。
std::vector<std::map<A,B>* > x;
它不会自动做到这一点,因为它不知道你想让谁来管理内存。当vector
超出范围时,是否应销毁map
的对象。如果最初的map
仍在范围内呢?
- C++为构建时间获取QDateTime的可靠方法
- 从持续时间构造std::chrono::system_clock::time_point
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 为什么字符串比较的 == 运算符相对于任一字符串长度线性时间(似乎)?
- 两个嵌套循环的运行时间复杂性:二次型还是线性
- 是否可以显示需要线性搜索的时间才能找到您在程序中找到的密钥
- 在线性时间内使用邻接列表创建对顶点
- 从文件中获取亚线性时间的输入
- 拆分动态分配的数组,无需线性时间复制
- 返回C++和时间复杂度的线性列表
- 使用递归在常量空间和线性时间中向后打印链表
- 如何在线性时间内生成一类稳定的二进制值
- 线性时间欧拉全函数计算
- 如何在次线性时间内从行主数组中选择列
- 向量复制构造函数C++:它必须是线性时间吗
- 为什么我的斐波那契动态规划没有给出线性时间?
- 一个数据结构的线性时间构造,如果两个字符串有两个共同的字母,则在常数时间内回答
- 线性搜索向量[i]的响应时间为0ms,而向量.at(i)的响应时间为0ms
- 有可能在线性时间内进行一般排序吗
- 给定一个排序数组和一个参数 k,求出线性时间内大于或等于 k 的两个数字的总和