std :: atomic :: operator ++真的按值返回吗?

时间:2012-11-05 11:20:26

标签: c++ c++11 operator-overloading atomic c++-standard-library

根据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在这方面的行为与内置类型不同?

2 个答案:

答案 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时,它会做两件事

  1. Atomic read-modify-write
  2. 原子载荷
  3. 他们是两个完全独立的行动。如果其他线程调用next,你的自动增量字段将得到错误的值!

答案 1 :(得分:2)

根据[C++11: 29.6.5/32][C++11: 29.6.5/10],是的,cppreference.com在这方面是正确的。

我没资格告诉你原因。