初始化std :: atomic_bool?
我想使用std::atomic_bool
因为我想有一个布尔值,应该由不同的线程访问。
这是一个static
成员variables。 问题是我想用false
作为第一个状态初始化它。 通常我会这样做: std::atomic_bool World::mStopEvent = false;
但是问题似乎是它不会把构造函数当作false
的。 那么我应该如何初始化这样一个variables呢? 我正在使用VS 2012。
这是Visual Studio 2012(称为VC11)中的一个已知问题 ,您应该对现有Connect项目进行投票,以便Microsoft知道这会影响更多人,因为他们推迟了修复。
嗨,
感谢您报告这个错误。 我是微软的STL维护者,我想让你知道,虽然这个错误在我们的数据库中仍然有效,但它在VC11 RTM(VS 2012 RTM)中不会被修复。 所有的错误对我们来说都很重要,但有一些比另外一些更为严重,并且成为我们优先级队列的首位。
我在所有STL的活动Connect错误中复制并粘贴了这个响应,但是以下简洁的注释特别适用于您的错误:
- 是的,我们在
atomic_bool
,atomic_int
等(atomic<bool>
,atomic<int>
等有他们)缺less这些构造函数。 29.5 [atomics.types.generic] / 7表示“应该按照表145中的规定命名与atomic<bool>
atomic_bool
对应的types,以及与指定的atomic<bool>
对应的命名typesatomic_bool
。每个命名types是要么是相应的专业化types定义,要么是相应专业化的基类,如果是基类,则应该支持与相应专业化相同的成员函数。 这使我真的想使用typedefs(1types比2types简单),但我需要看看是否会引入任何其他问题。我不能保证什么时候能解决这个bug,但是我们希望尽快这样做(我会在发生这种情况的时候再发一个回复) – 我们的第一个机会就是“out-band” Herb Sutter在2012年GoingNative会议上宣布推出VC11和VC12。
注意:Connect不会通知我有关评论。 如果您还有其他问题,请发邮件给我。
Stephan T. Lavavej高级开发人员 – Visual C ++库stl@microsoft.com
基本上,你现在需要使用std::atomic<T>
。
问题:
你不能使用复制初始化 ,因为std::atomic_bool
不是可复制的:
std::atomic_bool World::mStopEvent = false; // ERROR!
其实以上相当于:
std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR!
但是,您可以使用直接初始化 :
std::atomic_bool World::mStopEvent(false);
根据您的意愿,您可以select使用大括号代替括号:
std::atomic_bool World::mStopEvent{false};
BUG:
虽然复制初始化是非法的,不pipe你select什么编译器,似乎VC11附带的标准库的实现有一个错误,不会让你执行直接初始化。
那么我应该如何初始化这样一个variables呢?
解决方法:
作为一种可能的解决方法,您可以提供一对静态的getter / setter包装器,它们分别设置并返回primefaces布尔型标志的值,但是在确保它已经被初始化至less一次而不是一次之后期望的初始值以线程安全的方式(你可以考虑这种懒惰的初始化):
#include <atomic> #include <mutex> struct World { static bool is_stop_event_set() { std::call_once(mStopEventInitFlag, [] () { mStopEvent = false; }); return mStopEvent; } static void set_stop_event(bool value) { std::call_once(mStopEventInitFlag, [value] () { mStopEvent = value; }); mStopEvent = value; } static std::atomic_bool mStopEvent; static std::once_flag mStopEventInitFlag; }; std::atomic_bool World::mStopEvent; std::once_flag World::mStopEventInitFlag;
现在不是直接访问mStopEvent
,而是通过is_stop_event_set()
函数读取它的值:
#include <iostream> int main() { std::cout << World::is_stop_event_set(); // Will return false }
尝试这个:
atomic_bool my_bool = ATOMIC_VAR_INIT(false);
怎么样:
std::atomic_bool World::mStopEvent(false);