According to this prefix std::atomic<T>::operator++
returns a T
, so this code only increments v
once:
template<class T> void addTwo(std::atomic<T>& v) {
++(++v);
}
Also, std::atomic<T>::operator=
apparently returns a T
, so this code dereferences an invalid pointer that used to point to a temporary T
:
template<class T>
void setOneThenTwo(std::atomic<T>& v) {
auto ptr = &(v = 1);
*ptr = 2;
}
I am most certainly not suggesting that these code patterns are good practice, however it is highly surprising to me that std::atomic
breaks them. I always expect operator=
and prefix operator++
to return a reference to *this
.
Question: Is cppreference right about the return types here, and if so, is there a good reason for having std::atomic
behave differently than built-in types in this regard?
if operator++
returned a reference, it would have been a reference to std::atomic<T>
not to T
in which case you would need to do an additional load
to get the current value.
Imagine you've got a DBMS and you need to maintain an 'autoincrement' field
With operator++
retuning T
you can do this
class AutoIncrement
{
public:
AutoIncrement() : current (0) {}
unsigned int next()
{
return ++current;
}
private:
std::atomic<unsigned int> current;
};
Now imagine operator++
returns std::atomic<T>&
In that case when you do return ++current
it will do two things
They are two totally independent operations. If other thread calls next
in between you will get wrong value for your autoincrement field!
According to [C++11: 29.6.5/32]
and [C++11: 29.6.5/10]
, yes, cppreference.com is correct in this regard.
I'm not qualified to tell you why.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.