在类构造函数中初始化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()
,它是否安全?
答案 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 意味着这是唯一可接受的方式。