c++ - 为什么即使删除了复制构造函数,std::atomic 也会从 C++17 编译?
问题描述
我有一个简单的代码:
#include <atomic>
int main()
{
std::atomic<int> a = 0;
}
此代码在带有 -std=c++17 的 GCC 11.1.0 中编译得很好,但在 -std=c++14 和 -std=c++11 时编译失败。
使用已删除的函数 std::atomic::atomic(const std::atomic&)
这是为什么?在 C++17 类std::atomic
中仍然没有复制构造函数。为什么此代码对 -std=c++17 有效?
当然我知道首选的风格是使用{}
,但我只是好奇为什么上面的代码从 C++17 开始编译得很好。
解决方案
由于 C++17 保证了这种复制省略。对于std::atomic<int> a = 0;
,a
需要0
直接从初始化。
注意:上述规则未指定优化:纯右值和临时值的 C++17 核心语言规范与早期 C++ 修订版根本不同:不再有临时复制/移动。描述 C++17 机制的另一种方式是“未实现的值传递”:在没有实现临时值的情况下返回和使用纯右值。
在 C++17 之前,即使复制/移动操作(从初始化a
的临时std::atomic<int>
对象初始化0
)可能被优化(在复制初始化中),复制/移动构造函数仍然需要可访问。
最后一步通常是优化出来的,转换的结果直接在为目标对象分配的内存中构造,但是即使不使用适当的构造函数(移动或复制)也需要可访问。(直到 C++17)
推荐阅读
- php - 为什么可以打印发布到 php 的数据,但不能在 if 中进行比较。(仅限 esp8266。PC 网络浏览器正常工作)
- reactjs - 如何实现文本装饰:MaterialUI 'dotted'
- java - 如何使用自定义 LIKE 参数创建数据库视图?
- php - ajax 和 woocommerce 页面加载了两次
- ruby-on-rails - Rails 路由问题:不需要的路由
- amazon-web-services - 如何将 Web 服务部署到 Amazon EKS?
- java - 如何修复“未找到改造注释”。在简单的 GET 回调中?
- rabbitmq - 发布到消息队列的数百万条记录未显示在 RabbitMq 管理仪表板屏幕上
- clips - 如何在 CLIPS 中计算 Haversine 公式
- javascript - 检查对象中的嵌套数组是否包含空值