c++ - 为什么 Visual C++ 2015 允许 std::atomic 赋值?

标签 c++ c++11 gcc stdatomic visual-c++-2015

几天前,我写了如下内容:

struct A {
    std::atomic_bool b = false;
};

使用 VC++2015 编译器在 Visual Studio 2015 Update 3 中编译,没有弹出任何错误。
现在我在 Ubuntu 上用 GCC (5.4.0) 重新编译了同样的东西并得到了错误:

use of deleted function 'std::atomic::atomic(const std::atomic&)

我在 ideone 上遇到了同样的错误,设置为 C++14(不确定它使用的是哪个编译器版本)。

当然,将代码更改为以下内容可以解决 gcc 的问题:

struct A {
    std::atomic_bool b { false };
};

我的问题是:
1. 谁是正确的(符合 C++11),VC++ 还是 GCC?貌似VC++是从bool调用构造函数,而GCC调用的是复制构造函数(已删)
2. 为了在类声明中初始化原子的默认值,统一初始化(以上)是正确/首选的方法吗?或者我应该改用 ATOMIC_VAR_INIT 宏(呃!)?

struct A {
    std::atomic_bool b = ATOMIC_VAR_INIT(false);
};

最佳答案

这里VC就错了。在语义上,C++17 之前的代码 X x = y 表示调用 X tmp(y),然后调用 X(tmp) - 即,有一个语义上称为的复制构造函数。

虽然我知道的所有编译器都消除了中间调用(标准允许这样做),但程序仍然是病式的。看起来 VC 没有正确执行语义。

在 C++17 中,此调用的语义会发生变化,并且只需要一次初始化构造函数调用,因此代码将变得合式。

关于c++ - 为什么 Visual C++ 2015 允许 std::atomic 赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42300331/

相关文章:

c++ - 创建一个将字符串常量返回给枚举的类的廉价方法,反之亦然?

c++ - 在 Mac OS X .framework 中包含 GLEW 的正确方法是什么?

c++ - 从 C++ 调用 ScaLAPACK

c++ - 套接字和文件推荐的缓冲区大小

c++ - 为什么我的 DirectInput8 堆栈会溢出?

c++ - 迭代多个嵌套 vector

c++ - 二维数组 C++ 的列迭代器

c++ - 三角形图案

c++ - 为什么 auto 关键字不能与指向函数的指针的初始化列表一起使用?

c++ - 有人可以解释为什么我在这里收到 fatal error C1202 以及如何解决它吗?