std :: atomic_flag作为成员变量

时间:2014-06-26 18:11:31

标签: c++ c++11

在类构造函数中初始化std::atomic_flag的安全方法是什么?

This question似乎在问我要问的同一个问题 - 除了这里提问者抱怨编译问题。

我的问题与C ++标准本身有关。根据{{​​3}},未指定使用构造函数初始化程序语法初始化std::atomic_flag

std::atomic_flag static_flag = ATOMIC_FLAG_INIT; // static initialization,
// guaranteed to be available during dynamic initialization of static objects.

int main()
{
    std::atomic_flag automatic_flag = ATOMIC_FLAG_INIT; // guaranteed to work
//    std::atomic_flag another_flag(ATOMIC_FLAG_INIT); // unspecified
}

这些信息是否正确?如果是这样,我认为:

struct Foo
{
  Foo() : flag(ATOMIC_FLAG_INIT)
  { }

  std::atomic_flag flag;
};

...也未指明。那么,这是否意味着我们不能使用std::atomic_flag作为类的成员变量?或者,如果我们从类构造函数中简单地调用std::atomic_flag::clear(),它是否安全?

2 个答案:

答案 0 :(得分:12)

关于ATOMIC_FLAG_INIT使用的措辞自N3337改为N3936(目前的C ++ 14草案)。前者在复制初始化上下文中显示了示例中ATOMIC_FLAG_INIT宏的可能用法,这些宏是非规范性的,并未提及有关在其他初始化上下文中使用的任何内容。

N3936澄清了用法,并且不再列出复制初始化用法作为示例,而是作为描述本身的一部分。

§29.7/ 4 [atomics.flag]

  

ATOMIC_FLAG_INIT的定义方式应该可以用来   将类型为atomic_flag的对象初始化为清除状态。宏可用于   形式:

 atomic_flag guard = ATOMIC_FLAG_INIT;
     

未指定宏是否可用于其他初始化上下文。对于完整的静态持续时间对象,该初始化应该是静态的。除非使用ATOMIC_FLAG_INIT初始化,否则未指定atomic_flag对象的初始状态是设置还是清除。

讨论了这些变化的基本原理here

所以你是对的,不能依赖在成员初始化列表中使用宏。解决方案是使用非静态数据成员初始值设定项或 brace-or-equal-initializer 来初始化atomic_flag。然后它将在复制初始化上下文中初始化。

struct Foo
{
  std::atomic_flag flag = ATOMIC_FLAG_INIT;
};

答案 1 :(得分:2)

C ++ 11标准的实际文本(嗯,N1570)对ATOMIC_FLAG_INIT的定义是

  

7.17.8原子标志类型和操作

     

...

     

ATOMIC_FLAG_INIT可用于将atomic_flag初始化为。{1}}   清楚的状态。未明确初始化的atomic_flag   ATOMIC_FLAG_INIT最初处于不确定状态。

     

实施例

   atomic_flag guard = ATOMIC_FLAG_INIT;

C ++标准使用单词 initialize 来通常指代变量可以赋予初始值的所有各种方式。由于没有相反的措辞,我将意图读作atomic_flag guard(ATOMIC_FLAG_INIT),并且在构造函数初始化列表中使用ATOMIC_FLAG_INIT也是有效的而不是未指定的。我认为你引用的网站在单个例子中读得太多了。本标准中的示例不是规范性的,特别是,一个示例显示了一种做某事的方法 not 意味着这是唯一可接受的方式。