Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;访问一次_C++_C++11 - Fatal编程技术网

C++ c++;访问一次

C++ c++;访问一次,c++,c++11,C++,C++11,我正试图在c++11中实现与Linux宏ACCESS\u ONCE相当的功能。 ACCESS\u ONCE(x)获取x的地址,将其强制转换为指向与x相同类型的volatile的指针,然后取消引用它。这迫使编译器不通过该宏优化对x的访问(并使访问在此仅发生一次) 我试图在c++11中实现这一点,涉及到decltype: #define ACCESS_ONCE(x) (*static_cast<decltype(x) volatile *>(&(x))) 此操作失败并出现错误:

我正试图在c++11中实现与Linux宏ACCESS\u ONCE相当的功能。
ACCESS\u ONCE(x)
获取x的地址,将其强制转换为指向与x相同类型的volatile的指针,然后取消引用它。这迫使编译器不通过该宏优化对x的访问(并使访问在此仅发生一次)

我试图在c++11中实现这一点,涉及到
decltype

#define ACCESS_ONCE(x) (*static_cast<decltype(x) volatile *>(&(x)))
此操作失败并出现错误:

'volatile' qualifiers cannot be applied to 'void*&'

我做错了什么?

将宏更改为:

#define ACCESS_ONCE(x) (*static_cast<std::remove_reference<decltype(x)>::type volatile *>(&(x)))
#定义一次访问(x)(静态(x))
取消对指针的引用将导致引用。宏试图将其强制转换为
void*&volatile
而不是您想要的
void*volatile
。无法将volatile限定符应用于引用类型,因此必须使用std::remove\u reference将其更改为正常的非引用类型。

模板
template<typename T>
inline T volatile &access_once(T &t) {
    return static_cast<T volatile &>(t);
}
内联T易失性和一次性访问(T&T){ 返回静态_-cast(t); }

这避免了宏,更简单,因为类型推断和引用删除在模板签名中是隐式的,并且它避免了冗余的地址和差异运算符(引用类型之间的静态转换定义为执行与获取地址、转换然后取消引用相同的操作)。它的性能也一样,我不认为这取决于C++11中的任何内容。

非常感谢。这就解决了问题,并教会了我一些c++11技巧。避免宏——它们是为c黑客准备的。这里正确的强制转换是
const_cast
,尽管它的名称不同,它可以添加和删除
volatile
限定符以及
const
限定符。@PeteBecker我不同意<代码>静态_cast是这里的正确选择<代码>const_cast的功能比必要的功能更强大<代码>静态_cast允许添加cv限定符,因为此转换始终是安全的
const_cast
应保留用于实际需要删除cv限定符的不安全强制转换的情况。@DirkHolsopple-
static_cast
功能强大,因为它允许更改类型。@DirkHolsopple-这是一个循环参数:您坚持它只应用于“不安全”转换,所以它的使用给你留下了这样的印象。它告诉我cv限定符正在被修改。更改是否“安全”是次要的,取决于它们是否正确。如果我想检查正确性,我更希望得到一个提示,即只有cv限定符在更改。@DirkHolsopple-我的观点是,由于大多数使用
static\u cast
是更改对象的类型,而不是其cv限定符,使用
static\u cast
在执行安全操作(如添加cv-qualifier)时,会引起不值得注意的注意。它是否适用于已经易变的对象(您希望它的易变程度如何)?我建议在return语句和return类型中对T使用remove_volatile。它实际上对volatile对象有效。冗余volatile是合法的,不会引起任何问题。
template<typename T>
inline T volatile &access_once(T &t) {
    return static_cast<T volatile &>(t);
}