2014-11-03 41 views
4

看看這段代碼:在這種情況下,std :: stack :: push()和std :: stack :: emplace()是否有區別?

struct Dummy 
{ 
    int bla; 
    int blabla; 
    char character; 

    Dummy (int b, int bb, char c) 
     : bla(b), blabla(bb), character(c) 
    {} 
}; 

std::stack<Dummy> s; 
Dummy dummy; 
s.push(dummy); // (1) 
s.emplace(dummy); // (2) 

我看不出(1)(2)之間的差異。我知道emplace()當你的對象被添加的構造函數提供的參數是有用的,例如:

s.emplace(1, 2, 'c'); 

,但我不知道其中的差別是在我,因爲這兩個push()emplace()描述的情況應該是什麼請參考當地dummy對象,並使用copy ctor或類似的東西創建一個新對象。 push()是否在過程中創建了任何臨時對象?

+0

爲什麼你認爲需要有所不同?一般而言,emplace替代push,更通用,有時效率更高。 – rici 2014-11-03 15:42:44

+0

沒有什麼區別,因爲它們都構造了傳入的參數的副本。'emplace()'在你想完善前面的參數時很有用。 – 0x499602D2 2014-11-03 15:46:43

+0

由於您傳遞的參數,第二次調用Dummy :: Dummy(const Dummy&)嗎?我會看到一個使用emplace,比如s.emplace(); – Exceptyon 2014-11-03 15:50:12

回答

5

將不會有臨時工。對於標準,push樣子:

void push(const value_type& x) { c.push_back(x); } 
void push(value_type&& x) { c.push_back(std::move(x)); } 

emplace樣子:

template <class... Args> 
void emplace(Args&&... args) { 
    c.emplace_back(std::forward<Args>(args)...); 
} 

哪裏c是底層容器,默認爲deque<T>。因此,在前一種情況下,當您撥打推送電話時,您正在呼叫push(const Dummy&),這將通過Dummy(const Dummy&)創建一個新對象。在後一種情況下,您正在調用emplace_back(Dummy&),它通過Dummy(Dummy&)直接創建一個新對象。

你的情況 - 這兩個拷貝構造函數沒有區別。他們都會調用由編譯器隱式創建的平凡副本構造函數。所以你應該看到你的(1)(2)調用之間沒有任何行爲差異。

如果其中一個或另一個構造函數不存在(在這種情況下,其中一個或另一個不會編譯),或者它們做了不同的事情,那麼只會有區別。

+0

有一個隱式的'Dummy(Dummy&)'構造函數? – 0x499602D2 2014-11-03 15:53:06

+0

有一個隱含的'Dummy(const Dummy&)',它會被非const引用調用。 – Barry 2014-11-03 16:00:36

0

而不是採取value_type emplace採用參數的可變參數列表,這意味着您現在可以完全轉發參數並直接構造一個對象到容器中,而不需要臨時參數,這與可能涉及臨時參數的推入相反。

下面是標準清晰度的佈設: -

在堆棧的頂部推新元素。該元素就地構建,即不執行復制或移動操作。該元素的構造函數與提供給該函數的參數完全相同。

相關問題