2012-07-10 77 views
0

我想爲我的矢量使用工廠函數,並使用迭代器而不調用調整我以前的值的調整大小?如何使用.begin()和.end()沒有.resize()爲std :: vector?

是否有可能或缺少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; 
} 

謝謝:)

回答

8

要麼我不完全理解您的疑慮,要麼您誤導了您。 resize()不會修改容器中的任何現有元素(如果您調整爲較小的大小,則除去那些元素)。

現在,您的實際問題是您的程序中存在未定義的行爲。矢量有capacity() == nbr,但size() == 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()); 
+0

謝謝!完全忘記了back_inserter迭代器及其屬性:) – Quanteek 2012-07-10 15:16:55

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

它`錯誤。保留!=調整大小,只保留分配內存,如果我們需要它。 爲什麼你使用打印矢量調整大小?調整大小是調整矢量大小的函數,開始/結束不依賴於調整大小...

0

您的generate_n不會正確生成矢量值。矢量的大小爲0,所以雖然它看起來可以正常工作,但在寫入超出矢量的末尾時纔會運氣。你確實需要使用resize或類似的。或者(也可能是更高性能),您可以使用back_inserterstd::generate_n(std::back_inserter(v), nbr, factory());

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 - 在這種情況下你不需要它。

相關問題