InterlockedCompareExchange16的C ++短枚举问题(使用VS2012)

时间:2013-05-16 13:48:52

标签: c++11 enums volatile interlocked static-assert

引用了这个问题:Can an enum class be converted to the underlying type?

在我的代码中我有效:

enum class STATE : short
{
    EMPTY,
    PRESENT,
    PARTIAL,
};

volatile STATE state;

然后我写了一个typedef和一个static_assert

typedef volatile std::underlying_type<STATE> state_type;
static_assert (sizeof (state_type) == sizeof (short), "Error - unsafe for use with InterlockedCompareExchange16");

最后,我尝试使用InterlockedCompareExchange16

设置状态
if (InterlockedCompareExchange16 (static_cast<state_type *>(&state), STATE::PRESENT, STATE::EMPTY) == STATE::EMPTY)
{
}

我从VS2012收到以下错误:

  1. 我的static_assert未能抱怨state_type的尺寸与short的尺寸不同

  2. static_cast抱怨它无法从volatile STATE *投射到state_type *

  3. 任何人都可以给我任何关于如何最好地修复我的代码的指示吗?

1 个答案:

答案 0 :(得分:2)

来自std::underlying_type

  

定义类型的成员typedef类型,它是枚举T的基础类型。

更改为:

typedef typename std::underlying_type<STATE>::type state_type;
                                            //^^^^

强类型enum class的动机是阻止转换为int,因此尝试转换为基础类型与enum的预期用法冲突(请参阅{{ 3}})。

使用添加到c ++ 11的Strongly Typed Enums (revision 3)模板,而不是使用特定于操作系统的线程机制:

std::atomic<STATE> state(STATE::EMPTY);
STATE expected(STATE::EMPTY);
if (state.compare_exchange_strong(expected, STATE::PRESENT))
{
    // 'state' set to 'PRESENT'.
}

这消除了对static_assert的要求,并且不需要任何强制转换。