我正在尝试ACCESS_ONCE在c ++ 11中实现相当于Linux的宏.
ACCESS_ONCE(x)获取x的地址,强制转换为指向与x相同类型的volatile的指针,然后取消引用它.这会强制编译器不通过此宏优化对x的访问(并使访问仅在此处进行一次).
我在c ++ 11中尝试这样做涉及decltype:
#define ACCESS_ONCE(x) (*static_cast<decltype(x) volatile *>(&(x)))
Run Code Online (Sandbox Code Playgroud)
这适用于大多数情况,但我使用它一次:
void foo(void **bar) {
while (ACCESS_ONCE(*bar) != NULL)
;
}
Run Code Online (Sandbox Code Playgroud)
这失败并出现错误:
'volatile' qualifiers cannot be applied to 'void*&'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
template<typename T>
inline T volatile &access_once(T &t) {
return static_cast<T volatile &>(t);
}
Run Code Online (Sandbox Code Playgroud)
这避免了宏,因为类型推导和引用删除隐含在模板签名中,它避免了冗余的地址和引用操作符(引用类型之间的静态转换被定义为执行与获取地址,转换和然后解除引用).它的表现同样出色,我不认为这取决于C++ 11中的任何内容.
将宏更改为:
#define ACCESS_ONCE(x) (*static_cast<std::remove_reference<decltype(x)>::type volatile *>(&(x)))
Run Code Online (Sandbox Code Playgroud)
取消引用指针会产生引用.宏正在尝试将其转换为您想要的void *& volatile而不是void * volatile您想要的.您不能将volatile限定符应用于引用类型,因此必须使用std :: remove_reference将其更改为普通的非引用类型.