如何解决为什么即使删除了复制构造函数,std::atomic 也能从 C++17 编译?
我有一个简单的代码:
#include <atomic>
int main()
{
std::atomic<int> a = 0;
}
此代码在 GCC 11.1.0 和 -std=c++17 下编译良好,但在 -std=c++14 和 -std=c++11 时编译失败。
使用被删除的函数 std::atomic::atomic(const std::atomic&)
这是为什么?在 C++17 中,类 std::atomic
仍然没有复制构造函数。为什么此代码对 -std=c++17 有效?
当然我知道首选样式是使用 {}
,但我只是好奇为什么上面的代码从 C++17 开始就可以很好地编译。
解决方法
从 C++17 开始,这样的 copy elision 是有保证的。对于 std::atomic<int> a = 0;
,a
需要直接从 0
初始化。
注意:上面的规则没有指定优化:纯右值和临时值的 C++17 核心语言规范与早期的 C++ 修订版根本不同:不再有临时值可以复制/移动。另一种描述 C++17 机制的方法是“非物化值传递”:返回和使用纯右值,而不会物化一个临时值。
在 C++17 之前,即使复制/移动操作(从从 a
初始化的临时 std::atomic<int>
初始化 0
)可能被优化掉(在 {{3 }}),复制/移动构造函数仍然需要可访问。
最后一步通常被优化掉,转换的结果直接在为目标对象分配的内存中构造,但即使没有使用,也需要适当的构造函数(移动或复制)可访问。 (直到 C++17)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。