2013-04-04 44 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),编译器将无法解析该呼叫。