Ker*_*kic 1 c++ containers templates
我正在做一些作业,其中包括一个具有许多方法和构造函数的通用类,但我只对以下构造函数感兴趣,我从初始化列表中取出元素并将它们放入我的容器中:
template <typename T, template <typename...> class Container = std::vector>
class Tok{
Container<T> collection;
public:
Tok(std::initializer_list<T> list);
}
Run Code Online (Sandbox Code Playgroud)
我们被告知我们不能使用算法中的 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++;}
}
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,程序崩溃并抛出内存错误。然后我对其进行了一些更改,并使用下一个实现使其工作:
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);
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是为什么第一个不起作用,这两者之间有什么区别?(我使用开始而不是结束得到相同的结果)
插入到容器中std::vector可能会使迭代器失效。
在您的第一个示例中,在向 中插入内容后collection, ,it2不再有效(因为向量可能不得不重新分配其存储空间),但您将其递增并在下一次迭代中再次使用它。在您的第二个示例中,它有效,因为您在每次迭代时都会获得一个新的结束迭代器。
您可以使用insert的返回值解决第一个示例中的问题。它将为插入的值返回一个有效的迭代器,您可以将其分配给it2。如果您想在容器中间插入多个元素,这也适用,如下所示:
auto pos = getInsertPosition();
for(auto &val : source) {
pos = destination.insert(pos, val);
}
Run Code Online (Sandbox Code Playgroud)