根据this前缀std::atomic<T>::operator++
返回T
,因此此代码只会增加v
一次:
template<class T> void addTwo(std::atomic<T>& v) {
++(++v);
}
此外,std::atomic<T>::operator=
apparently会返回T
,因此此代码会取消引用用于指向临时T
的无效指针:
template<class T>
void setOneThenTwo(std::atomic<T>& v) {
auto ptr = &(v = 1);
*ptr = 2;
}
我肯定不会建议这些代码模式是很好的做法,但是std::atomic
打破它们对我来说非常令人惊讶。我一直希望operator=
和前缀operator++
返回对*this
的引用。
问题:此处的返回类型是否正确cppreference,如果是这样,是否有充分的理由让std::atomic
在这方面的行为与内置类型不同?
答案 0 :(得分:20)
如果operator++
返回了引用,那么它将引用std::atomic<T>
而不是T
,在这种情况下,您需要额外load
才能获得当前价值。
想象一下,你有一个DBMS,你需要保持一个'自动增量'字段
通过operator++
重新调整T
,您可以执行此操作
class AutoIncrement
{
public:
AutoIncrement() : current (0) {}
unsigned int next()
{
return ++current;
}
private:
std::atomic<unsigned int> current;
};
现在假设operator++
返回std::atomic<T>&
在这种情况下,当你执行return ++current
时,它会做两件事
他们是两个完全独立的行动。如果其他线程调用next
,你的自动增量字段将得到错误的值!
答案 1 :(得分:2)
根据[C++11: 29.6.5/32]
和[C++11: 29.6.5/10]
,是的,cppreference.com在这方面是正确的。
我没资格告诉你原因。