【问题标题】:insertion into vector插入向量
【发布时间】:2012-09-20 12:40:20
【问题描述】:

我是否认为这个看似无辜的代码相当危险?

template<typename T>
void insertLast(std::vector<T>& v)
{
    if(v.empty()) return;  
    v.insert(v.begin(), v.back());
}

阅读一些答案后的一些澄清..

好吧,我并不是真的在问如何将一个元素插入到向量中,而是我做了一个虚拟的情况来质疑一个原则。换句话说,你认为有必要制作一个副本吗(这里创建了一个临时的..并且保证对临时对象的 const 引用):

template<typename T>
void insertLast(std::vector<T>& v)
{
    if(v.empty()) return;  
    v.insert(v.begin(), T(v.back()));
}

【问题讨论】:

  • 它不会编译,因为您不能在 const 引用上调用 insert。你认为那是危险的吗?
  • 它还需要typename T 来编译。
  • 您不会混淆back 和end 吧?这是一个简单的错误,但完全改变了代码的含义
  • 如果您修复了template&lt;T&gt; 并删除了const,它应该可以完美运行。
  • @jozefg 在这种情况下,insert() 需要 3 个参数。

标签: c++ stl vector insertion


【解决方案1】:

这对我来说似乎也很危险,因为 vector.back() 返回引用,并且

插入向量末端以外的位置是通过将位置和向量末端之间的所有元素移动到它们的新位置,然后插入新元素来执行的 (来自here)

除非我误解了,否则传递给insert 的引用将变为“无效”(如果没有发生重新分配,则它不能包含最后一个元素,而是前一个元素;否则它仍然可能是正确的,但我想这不能保证。

在某些情况下,某些优化器可能会隐藏错误(我猜它永远不会发生在对象上,但可能会发生在原语上),所以你会得到预期的结果,但总的来说我不会依赖这种行为。

【讨论】:

    【解决方案2】:

    假设您解决了 cmets 中提到的两点以进行编译,这将运行但每次运行时都会在向量的前面留下一个垃圾值,因为 vector.back() 返回参考。

    它看起来像下面这样:

    template<typename T>
    void insertLast(std::vector<T>& v)
    {
        if(v.empty()) return;  
        v.insert(v.begin(), v.end() - 1, v.end());
    }
    

    这将安全地插入向量中的最后一个元素,使其也是第一个元素....假设这是所需的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      相关资源
      最近更新 更多