MyTinySTL icon indicating copy to clipboard operation
MyTinySTL copied to clipboard

Vector的插入函数是否可以简化一下?

Open Yuri-Zero opened this issue 4 years ago • 2 comments

在Vector的插入函数【特指 iterator insert(const_iterator pos, const value_type& value)这一重载】里中的一个判断分支 如果容量大于元素数量,且传入的迭代器不为end_时的代码我觉得可以简化一下 也就是这段:

  else if (end_ != cap_)
  {
    auto new_end = end_;
    data_allocator::construct(mystl::address_of(*end_), *(end_ - 1));
    ++new_end;
    auto value_copy = value;  // 避免元素因以下复制操作而被改变
    mystl::copy_backward(xpos, end_ - 1, end_);
    *xpos = mystl::move(value_copy);
    end_ = new_end;
  }

我觉得,vector储存元素的内存地址既然是连续的,就没有必要用allocator专门来给end_重新构造一次来储存最后一个元素了吧。 可以直接利用copy_backward来实现元素复制。 我的实现:

            else if (end_ != cap_)
            {
                auto value_copy = value;
                ++end_;
                std::copy_backward(x_pos, end_ - 1, end_);//我暂时仍在使用stl提供的算法
                *x_pos = std::move(value_copy);
            }

我是一个C++新手,理解可能有误,如果有错误,请指正!

Yuri-Zero avatar Feb 19 '21 03:02 Yuri-Zero

我的浅薄理解是,因为end_的位置还没有构造对象,所以如果直接调用copy_backword,那么将来要delete的时候,会析构对象,但是这个地址上并没有创建过对象。也就是在STL中construct和destroy要像new和delete一样成对使用,不然就有bug

meixingshi avatar Mar 03 '21 05:03 meixingshi

C++ 的初始化和赋值是不同的。 copy_backward 只会对已存在的对象赋值,但我们需要在未构造对象的位置进行初始化。

frederick-vs-ja avatar Jan 13 '23 03:01 frederick-vs-ja