4

以下代码失败push_back并成功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抛弃限定符。volatile

但是,emplace_back 需要一个引用(右值引用是引用)。为什么要区别对待?

4

1 回答 1

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为长度为 1 的参数包,其唯一元素具有类型int volatile&(参见第 14.8.2.1/3 段)。

push_back()另一方面,的重载是std::vector<>类模板的常规成员函数,调用它们时不会进行类型推导。由于对 non- 的引用volatile不能绑定到限定为的对象volatile(参见第 8.5.3/4-5 段),编译器将无法解析调用。

于 2013-04-04T17:02:27.513 回答