聚合初始化原子成员

Initialize atomic members in aggregate

似乎无法使用 C++14 初始化聚合中的原子成员。以下不起作用 (live on gcc 8.0.1):

#include <atomic>
#include <iostream>

struct stru {
  std::atomic_int32_t val_0;
  std::atomic_int32_t val_1;
};

int main() {
  auto p = new stru{0, 1};
  std::cout << p->val_0 << ", " << p->val_1 << std::endl; 
}

错误信息:

error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
   auto p = new stru{0, 1};
                     ^

这是因为原子类型既不可复制也不可移动,因此不可复制初始化。然而,以下似乎有效(live on gcc 8.0.1)。

#include <atomic>
#include <iostream>

struct stru {
  std::atomic_int32_t val_0;
  std::atomic_int32_t val_1;
};

int main() {
  auto p = new stru{};
  std::cout << p->val_0 << ", " << p->val_1 << std::endl; 
}

这有效地执行了零初始化,因此无法初始化为零以外的值。有没有办法初始化为其他指定值?

10 不是 std::atomic_int32_t。以下作品:

#include <atomic>
#include <iostream>

struct stru {
  std::atomic_int32_t val_0;
  std::atomic_int32_t val_1;
};

int main() {
  auto p = new stru{{0}, {1}};
  std::cout << p->val_0 << ", " << p->val_1 << std::endl; 
}

编辑:为什么会这样? Copy initialization kicks in 对于初始化列表中的每个元素:

Each direct public...non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.

在您的示例中,10 被隐式转换为 std::atomic_int32_t,并且 std::atomic_int32_t 不能从 [=] 变为 copy-initialized 13=]。在额外的 {} 版本中,val_0val_1 是从 std::initializer_list<int> 复制初始化的,这很好。

Patrick 的 works, but his explanation doesn't look right to me. So I post the explanation I find here. For the code auto p = new stru{{0}, {1}}; aggregate initialization 效果:

If the initializer clause is a nested braced-init-list (which is not an expression), the corresponding array element/class member/public base (since C++17) is list-initialized from that clause: aggregate initialization is recursive.

因此,成员不是复制初始化,而是从 braced-init-list 复制 list-initialized。