2012-11-05 11 views
13
Tを返し std::atomic<T>::operator++ thisプレフィックスによれば

ので、このコードは一度だけvをインクリメント:またstd :: atomic :: operator ++は本当に値で復帰しますか?

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

'operator ='が 'T'を返した場合、'&(v = 1) 'はコンパイルすべきではないでしょうか? –

+0

@ R.MartinhoFernandes:これは一時的な価値であるためですか? –

+0

左辺値を返しますか?もしそうでなければ、2番目の++はコンパイルされませんので、少なくともあなたはバグの行動から救われるでしょう。 – CashCow

答えて

20

operator++参照を返した場合、それはあなたが現在の値を取得するために、追加のloadを行う必要があります。その場合にはstd::atomic<T>にないTへの参照されていると思います。

あなたはDBMSを持っているし、あなたがこの

class AutoIncrement 
{ 
public: 
    AutoIncrement() : current (0) {} 

    unsigned int next() 
    { 
     return ++current; 
    } 

private: 
    std::atomic<unsigned int> current; 
}; 

今ときその場合operator++戻りstd::atomic<T>& を想像行うことができますT再調整operator++で「自動インクリメント」欄

を維持する必要が想像してあなたはreturn ++currentそれは2つのことを行います

  1. アトミックレアD・モディファイ・ライト
  2. 原子力負荷

彼らは2つの完全に独立した操作です。その間に他のスレッドがnextを呼び出すと、あなたのautoincrementフィールドの値が間違っています!

+4

+1。要するに、原子(増分と新しい値を返す)は原子の増分よりもはるかに有用であり、原子オブジェクトへの参照を返すので、デザイナーはやや驚くべき復帰型を正当化すると感じているからです。 –

+0

あなたの回答を編集で欺いてはいけません。これはロールバックされました。 –

2

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

私はその理由を伝える資格がありません。

関連する問題