2013-05-15 110 views
8

模板類vector內的許多方法需要常量引用value_type對象,例如:std :: vector的resize方法背後的設計原理是什麼?

void push_back (const value_type& val); 

resize取其value_type參數由值:

void resize (size_type n, value_type val = value_type()); 

作爲非專家C++程序員我只能想到這個選擇的缺點(例如,如果size_of(value_type)是足夠大的堆棧溢出可能發生)。我想問一些對語言有更多見解的人是這樣的:

這個選擇背後的設計原理是什麼?

+1

@ user814628這聽上去不是我的權利。唯一一次'value_type val = value_type()'可能不起作用,如果'value_type'有一個帶有非const引用的複製構造函數。 –

+0

我以前從未注意到,甚至有*是第二個參數來調整大小(...)!我想我今天已經學會了我的一件事,現在可以直到明天。 :-P – aldo

回答

9
void resize(size_type count, T value = T()); 

此功能已經從C++ 11除去

C++ 11具有resize()two overloads

void resize(size_type count); 
void resize(size_type count, const value_type& value); 

這是非常簡單易懂。第一個使用value_type類型的默認構造對象在調整大小時填充矢量,第二個用於調整大小時從中複製的值。

+0

我的不好!我懶得從[cplusplus](http://www.cplusplus.com/reference/vector/vector/resize/)而不是從標準草案中查看C++ 11原型,並且在那裏顯然是錯誤的! – Massimiliano

+5

@Massimiliano:cplusplus對於C++教程來說是一個糟糕的壞站點:即使是C++ 11簽名也不正確。它缺少'const&'。 **首選[cppreference.com](http://en.cppreference.com/w/cpp)在cplusplus.com ** – Nawaz

+0

感謝您的提示,我將開始使用cppreference代替。 – Massimiliano

6

這似乎是一個設計缺陷,現在已經修復。

STL defects 679

的C++ 98標準規定,單獨的容器中的一個成員函數經過值而不是通過const引用它的參數(T)報價:

空隙大小調整(SIZE_TYPE sz,T c = T());

這個事實多年來一直在討論/爭論,第一次甚至在C++ 98被批准之前。對於按值傳遞該參數的基本原理一直以:

,以便在自引用的語句,保證工作,例如:

v.resize(v.size() + 1, v[0]); 

但是這個理由是不能令人信服的作爲的push_back簽名是:

void push_back(const T& x); 

而push_back具有類似的調整大小(附加)的語義。而且還的push_back必須在自參照的情況下工作:

v.push_back(v[0]); // must work 

與按值傳遞T中的問題是,它可以顯著比通過引用傳遞更加昂貴。反過來也是如此,但是當它是真的時,它通常遠不那麼戲劇化(例如對於標量類型)。

即使移動語義可用,通過值傳遞此參數可能會很昂貴。例如,考慮矢量>:

std::vector<int> x(1000); 
std::vector<std::vector<int>> v; 
... 
v.resize(v.size()+1, x); 

在通過噪聲值的情況下,x被複制一次要調整的參數。然後在內部,由於代碼無法在編譯時知道調整大小向量的大小,因此x通常會從調整大小的參數複製(不移動)到其在向量中的適當位置。

隨着傳遞由const的引用,在上述例子中的X只需進行一次複製。在這種情況下,x具有昂貴的拷貝構造函數,因此可以保存的任何拷貝都可以節省大量的資源。

如果我們能高效地爲的push_back,我們應該是高效的大小調整爲好。使用參考參數調整大小已被編碼並在CodeWarrior庫中發貨,但沒有我知道的問題報告。

建議分辨率:

變化23.3.3 [雙端隊列],P2:

class deque { 
    ... 
    void resize(size_type sz, const T& c); 

變化23.3.3.3 [deque.capacity],P3:

void resize(size_type sz, const T& c); 

更改23.3。 5 [list],p2:

class list { 
    ... 
    void resize(size_type sz, const T& c); 

Ch安格23.3.5.3 [list.capacity],P3:

void resize(size_type sz, const T& c); 

變化23.3.6 [載體],P2:

class vector { 
    ... 
    void resize(size_type sz, const T& c); 

變化23.3.6.3 [vector.capacity],P11:

void resize(size_type sz, const T& c); 
相關問題