初始化聚合中的原子成员

时间:2018-02-17 03:22:51

标签: c++ c++14 language-lawyer stdatomic aggregate-initialization

似乎无法使用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; 
}

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

2 个答案:

答案 0 :(得分:2)

帕特里克的solution有效,但他的解释看起来并不合适。所以我发布了我在这里找到的解释。对于代码auto p = new stru{{0}, {1}}; aggregate initialization启动效果:

  

如果initializer子句是嵌套的braced-init-list(不是   表达式),相应的数组元素/类成员/ public   base(自C ++ 17开始)是从该子句列表初始化的:aggregate   初始化是递归的。

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

答案 1 :(得分:-1)

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

  

每个直接公共...非静态类成员,按照类定义中的数组下标/外观的顺序,从初始化列表的相应子句进行复制初始化。

在您的示例中,10被隐式转换为std::atomic_int32_t,而std::atomic_int32_t无法从std::atomic_int32_t进行复制初始化。在额外{}版本中,val_0val_1是从std::initializer_list<int> s初始化的副本,这很好。