c++ - 在扩展期间将 vector 成员插入 vector : vector. push_back(vector[0])

标签 c++ vector

我正在用 C++ 编写自定义 vector 类。我对这样的代码有疑问:

    vector<T> vec;
    vec.push_back(one);
    vec.push_back(two);
    vec.push_back(vec[0]);

push_back的定义如下:

    void push_back(const T & v)

避免不必要的复制。它的实现看起来像

    if (size == capacity)
    {
        allocate new storage
        copy old values into new storage
        // 2
        delete old storage
        fix pointers and counters
    }
    // 1
    copy v at the end of storage

如果我们想压入已经在 vector 中的元素并且 vector 需要扩展(大小等于它的容量),就会出现问题。如果我们这样做 (vec.push_back(vec[0])) 那么在 //1 处,它已经被释放了。所以我们需要它的拷贝。另一种选择是在扩展期间将其添加到 //2 的某处,但这看起来并不漂亮。

你会如何解决这个问题?

最佳答案

在我见过的一些 STL 实现中(例如当前的 VS2010),它们首先检查指向要添加的新数据项的指针是否在 vector 缓冲区的当前范围内。

如果是,则找到 vector 中数据位置的索引位置(不是指针!)。即使底层缓冲区被重新分配,这也不会改变。一旦缓冲区扩展(无论是否涉及实际重新分配),就可以从索引位置安全地复制数据项。

我想你提到过的另一种选择是在重新分配缓冲区之前获取要添加的数据项的本地(堆栈)拷贝,以防该项在 vector 内部。显然,如果数据类型的复制成本非常高(可能像另一种 vector ??),这可能不是一个好主意。

希望这对您有所帮助。

关于c++ - 在扩展期间将 vector 成员插入 vector : vector. push_back(vector[0]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5920456/

相关文章:

c++ - 从输出流中删除输入

c++ - Arduino Mega 上的奇怪计算

c++ - 在使用单独的规则定义和实例化时,Boost Spirit X3 AST 无法处理语义操作

C++ 静态与非静态类成员

c++ - 有没有办法从 Linux 发行版二进制文件中转储带有行号的堆栈跟踪?

c++ - 使用 fstream 读取带有 float 的 vector

c++ - 如何查明某个字符串是否包含在 std::vector 的任何字符串中?

c++ - 给定起点和终点以及距离,计算沿线的点

c++ - 如何使用带有 std::initializer_list 的构造函数设计类?

C++ OutputIterator 后递增要求