使用算法中的插入函数将元素插入空容器中,未给出预期的结果

Inserting elements in an empty container using insert function from algorithm not giving expected results

本文关键字:插入 结果 算法 函数 元素      更新时间:2023-10-16

我正在做一些功课,其中包括一个包含大量方法和构造函数的泛型类,但我只对以下构造函数感兴趣,我从初始值设定项列表中获取元素并将它们放入我的容器中:

template <typename T, template <typename...> class Container = std::vector>
class Tok{
    Container<T> collection;
    public:
    Tok(std::initializer_list<T> list);
}

我们被告知我们不能使用算法中的push_back函数,而只能使用算法中的插入函数插入元素。首先,我像这样实现了构造函数:

template <typename T, template <typename...> class Container>
Tok<T,Container>::Tok(std::initializer_list<T> list){
auto it2=collection.end();
    for(auto it1=list.begin(); it1!=list.end(); it1++) {
        {collection.insert(it2,*it1); it2++;}
    }
}

但它没有用,程序崩溃并抛出内存错误。然后我稍微改变了它,并使用下一个实现让它工作:

template <typename T, template <typename...> class Container>
Tok<T,Container>::Tok(std::initializer_list<T> list){
    for(auto it=list.begin(); it!=list.end(); it++) 
        collection.insert(collection.end(),*it);
}

现在我的问题是为什么第一个不起作用,这两者之间有什么区别?(我使用开始而不是结束得到相同的结果(

插入像std::vector这样的容器可能会使迭代器失效。

在您的第一个示例中,在将某些内容插入 collection 后,it2 不再有效(因为向量可能不得不重新分配其存储(,但您递增它并再次使用它进行下一次迭代。在第二个示例中,它之所以有效,是因为每次迭代都会获得一个新的结束迭代器。

您可以在第一个示例中使用 insert 的返回值来解决此问题。它将向插入的值返回一个有效的迭代器,您可以将其分配给it2。如果要将多个元素插入容器中间,这也可以工作,如下所示:

auto pos = getInsertPosition();
for(auto &val : source) {
    pos = destination.insert(pos, val);
}

在第一种情况下,当您开始添加元素时,您将使 it2 迭代器失效。把它看成:结局变了,如果你愿意的话。

第二种情况下,在每次迭代中,您都会查询一个新的 end(( 迭代器,因此您始终会得到一个有效的迭代器。

您可以在那里找到规则:迭代器失效规则