如何为std :: vector设置没有.resize()的有效.begin()和.end()?

时间:2012-07-10 14:54:01

标签: c++ stl

我想为我的vector使用一个工厂函数,并且还使用迭代器而不调用resize来打破我之前的值?

是否有可能或者我错过了STL设计中的一点?

#include <vector>
#include <algorithm>
#include <iostream>

struct A
{
    A():_x(42){}
    A(double x):_x(x){}
    double _x;
};

struct factory
{
    A operator()()
    {
        return A(3.14);
    }
};

int main()
{
    std::vector<A> v;
    int nbr = 3;
    v.reserve(nbr);
    std::generate_n(v.begin(), nbr, factory());

    std::cout << "Good values" << std::endl;
    for(int i = 0 ; i < nbr ; ++i)
        std::cout << v[i]._x << std::endl;

    v.resize(nbr); //How I can have the syntax below without the resize which blows my previous values ?

    std::cout << "resize has been called so values are bad (i.e default ctor)" << std::endl;
    for(std::vector<A>::iterator it = v.begin() ; it != v.end() ; ++it)
        std::cout << (*it)._x << std::endl;
}

谢谢:)

4 个答案:

答案 0 :(得分:8)

要么我不太了解你的担忧,否则你会被误导。 resize()不会修改容器中的任何现有元素(除非您调整为较小尺寸时删除的元素除外)。

现在,您的实际问题是您的程序中存在未定义的行为。当您调用capacity() == nbr时,该向量具有size() == 0generate_n,并且该文件超出了容器的末尾。有两种解决方案,首先您可以在调用generate_n之前调整的大小:

std::vector<A> v;
int nbr = 3;
v.resize(nbr);
std::generate_n(v.begin(), nbr, factory());

否则你可以改变迭代器的类型:

std::vector<A> v;
int nbr = 3;
v.reserve(nbr);
std::generate_n(std::back_inserter(v), nbr, factory());

答案 1 :(得分:0)

v.reserve(nbr);
std::generate_n(v.begin(), nbr, factory());

这是错误的。保留!=调整大小,保留仅在需要时分配内存。 为什么使用resize作为打印矢量?调整大小是调整大小向量的函数,开始/结束不依赖于调整大小...

答案 2 :(得分:0)

您的generate_n未正确生成向量中的值。向量的大小为0,所以虽然它可能看起来工作正常,但是当你在向量的末尾写入时,你只是获得了运气。你确实需要使用resize或类似的。或者(可能更高效)您可以使用back_inserterstd::generate_n(std::back_inserter(v), nbr, factory());

答案 3 :(得分:0)

代码的第一部分已经破了。要创建向量元素,您必须调用resize,而不是reservereserve只能通过分配原始内存来保留未来的向量容量,但它不会创建(构造)实数向量元素。通常不允许您访问位于矢量大小和矢量容量之间的矢量元素。

您调用了reserve,然后尝试使用您的向量,就像已经构造了元素一样:您为它们赋值并尝试读取和打印这些值。在一般情况下,这是非法的,它通常会导致未定义的行为。同时,向量的大小仍为0,这是您尝试通过稍后对resize的奇怪调用来补偿的。

您需要在一开始就致电resize。从一开始就创建一个具有适当数量元素的向量。 (这也可以通过将初始大小传递给向量的构造函数来完成。)

例如,只需执行

int nbr = 3;
std::vector<A> v(nbr);
std::generate_n(v.begin(), nbr, factory());

std::vector<A> v;
int nbr = 3;
v.resize(nbr);
std::generate_n(v.begin(), nbr, factory());

你完成了。忘记reserve - 在这种情况下你不需要它。