8

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

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

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

使用已删除的函数 '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);
};
4

1 回答 1

2

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

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

在 C++17 中,这个调用的语义会改变,并且只需要一个初始化构造函数调用,因此代码将变得格式良好。

于 2017-02-17T15:22:23.567 回答