Push_back与emplace_back的易失性
push_back vs emplace_back with a volatile
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
也接受引用(右值引用就是引用)。为什么会有不同的待遇?
这是因为它们在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<>
类模板的常规成员函数,在调用它们时不进行类型演绎。由于对非volatile
的引用不能绑定到限定为volatile
的对象(参见第8.5.3/4-5段),编译器将无法解析调用。
相关文章:
- 易失性sig_atomic_t的内存安全性
- C++易失性:保证 32 位访问?
- 避免易失性和非易失性成员函数的代码重复
- 当 2 个线程共享同一物理内核时,具有错误共享的易失性增量在发布中的运行速度比在调试中慢
- 如何访问常量易失性 std::array?
- 为什么在 C++20 中弃用易失性?
- 根据 MSVC,具有易失性成员的结构不再是 POD
- 是否允许编译器优化掉局部易失性变量
- 访问共享内存而不使用易失性、std::atomic、信号量、互斥锁和自旋锁
- 如何避免对无锁程序使用易失性?
- C++:易失性实例中的易失性成员函数 - 将数组分配给指针是无效的转换?
- g++ 6.3,avx 内联函数上的 Kahan 求和用易失性关键字进行序列化
- 是什么让这种易失性打破了结构的指针算法?
- 如果不需要易失性,为什么 std::atomic 方法会提供易失性重载
- *(易失性无符号整数 *) 的含义 0x00 = 0x00;
- 使用易失性 c 字符串和 std::cout
- 易失性结构 = 结构不可能,为什么?
- 如何强制 GCC 以线性方式转换易失性内联程序集语句
- 我可以使用互斥锁或关键字(静态)代替C++中的易失性吗?
- 兼容的声明 __attribute__ ((节( ".abc.dfe" ))) 常量易失性 uint8 属性变量 = 0;- 符合MISRA标准