j5w*_*j5w 1 c++ operator-overloading language-lawyer stdatomic c++17
我似乎无法在商店之后获得原子对象的地址。
例如
std::atomic<int> i;
std::atomic<int>* p = &++i; // doesn't work
auto* p = &++i; // doesn't work
// below works:
++i;
auto* p = &i;
Run Code Online (Sandbox Code Playgroud)
这里发生了什么,为什么?
澄清一下:我知道它返回一个 r 值。为什么它不返回原始对象,this?这是一个有目的的设计选择还是一个疏忽?
更具体地说,这个要求的幕后发生了什么?
虽然预增量运算符通常通过引用返回其操作数,但在std::atomic整数的情况下,它将新值作为临时值返回。因此,在您的示例++i中,不会返回对atomic<int> i自身的引用,而是返回i(即 int)的新值。您可以在以下位置查看:https : //en.cppreference.com/w/cpp/atomic/atomic/operator_arith
返回对原始 的引用会产生误导甚至危险atomic<int>,因为通过该引用访问 int 值需要第二次单独的读取操作——因此它的值可能与增量时的值不同。(这与您的示例代码并不是特别相关,因为您只是试图获取指向被引用对象的指针,但某些代码实际上会在之后访问该值,++因此这就是无法返回引用的原因。)
换句话说,如果++i返回对 的引用atomic<int> i,则
int j = ++i;
Run Code Online (Sandbox Code Playgroud)
将相当于
++i;
// ...other threads may modify the value of `i` here!...
int j = i;
Run Code Online (Sandbox Code Playgroud)
原子的全部意义在于将读取和写入作为不可分割的操作一起执行,因此++i必须在内部使用硬件/操作系统原子操作来同时读取和递增整数,因此新值作为临时返回。
如果您很想知道幕后是什么,这里是 libc++ 的实现,您可以在其中看到operator++简单地调用fetch_add(1)并返回结果 + 1。