14

このプレフィックスによると、をstd::atomic<T>::operator++返すため、このコードは1回Tだけインクリメントします。v

template<class T> void addTwo(std::atomic<T>& v) {
  ++(++v);
}

また、std::atomic<T>::operator= 明らかにを返すTので、このコードは一時的なものを指すために使用された無効なポインターを逆参照しますT

template<class T>
void setOneThenTwo(std::atomic<T>& v) {
  auto ptr = &(v = 1);
  *ptr = 2;
}

私はこれらのコードパターンが良い習慣であることを示唆しているわけではありませんが、std::atomicそれらを破ることは私にとって非常に驚くべきことです。operator=私は常に、プレフィックスoperator++がへの参照を返すことを期待してい*thisます。

質問:std::atomicここでの戻り型についてのcppreferenceは正しいですか?もしそうなら、この点で組み込み型とは異なる動作をする正当な理由がありますか?

4

2 に答える 2

21

参照が返された場合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それは2つのことをします

  1. アトミックリードモディファイライト
  2. 原子負荷

これらは2つの完全に独立した操作です。間に他のスレッドが呼び出さnextれた場合、自動インクリメントフィールドの値が間違ってしまいます。

于 2012-11-05T11:36:35.380 に答える
2

とによる[C++11: 29.6.5/32][C++11: 29.6.5/10]、はい、cppreference.comはこの点で正しいです。

理由をお話しする資格はありません。

于 2012-11-05T11:24:07.530 に答える