2013-04-04 78 views
4

下面的代碼失敗了push_back併成功爲emplace_back的push_back VS emplace_back與揮發性

#include <vector> 
volatile int x = 0; 
int main() 
{   
    std::vector<int> vec; 
    vec.emplace_back(x); 
    vec.push_back(x); // error: no matching function for call to 'std::vector<int>::push_back(volatile int&)' 
} 

我明白push_back failes因爲它需要一個參考,並嘗試從基準隱含拋棄volatile預選賽。

但是,emplace_back需要參考(右值參考是參考)。爲什麼它被區別對待?

+0

也許這個職位:http://stackoverflow.com/questions/4303513/push-back-vs-emplace-back – taocp 2013-04-04 17:00:36

+0

我明白這不是真的問題,但如果你需要一個解決方法轉換類型:'vec .push_back(static_cast (x));'(或者'int(x)'或'(int)x')。 – 2013-04-04 17:21:43

回答

8

這是因爲它們是如何在C++ 11標準中定義的。第23.3.6.1指定他們的簽名:

template <class... Args> void emplace_back(Args&&... args); 
void push_back(const T& x); 
void push_back(T&& x); 

雖然push_back()可用過載的參數沒有任何volatile資格,該emplace_back()函數模板的參數可以綁定到左值與任何cv企業資質。

但是,emplace_back也需要引用(右值引用是引用)。爲什麼它的處理方式不同?

是的,因爲emplace_back()是一個函數模板,和類型推導將推斷Args是長度爲一的參數組中,其唯一的元件具有類型int volatile&(見段落14.8.2.1/3)。

另一方面,push_back()的重載是std::vector<>類模板的常規成員函數,並且在調用它們時沒有類型推演。由於對非volatile的引用無法綁定到合格爲volatile的對象(請參見段落8.5.3/4-5),編譯器將無法解析該呼叫。