0

我想为我的向量使用工厂函数,并且还使用迭代器而不调用调整大小,这会破坏我以前的值?

有可能还是我在 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

4 回答 4

8

要么我不太明白你的担心,要么你被误导了。resize()不会修改容器中的任何现有元素(如果您将大小调整为较小的尺寸,则移除的元素除外)。

现在,您的实际问题是您的程序中有未定义的行为。向量有capacity() == nbrbutsize() == 0当你调用时generate_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());
于 2012-07-10T14:59:07.740 回答
0

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

你打电话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- 在这种情况下你不需要它。

于 2012-07-10T15:00:12.917 回答
0
v.reserve(nbr);
std::generate_n(v.begin(), nbr, factory());

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

于 2012-07-10T14:57:38.367 回答
0

generate_n没有正确地将值生成到向量中。向量的大小为 0,因此虽然它看起来可以正常工作,但在超出向量末尾的情况下,您只是运气好。你确实需要使用resize或类似的。或者(并且可能更高效)您可以使用back_inserterstd::generate_n(std::back_inserter(v), nbr, factory());

于 2012-07-10T14:58:33.987 回答