2012-11-05 6 views
13

Nach this Präfix std::atomic<T>::operator++ eine T zurückgibt, so dass dieser Code inkrementiert nur v einmal:Liefert std :: atomic :: operator ++ wirklich nach Wert?

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

, auch std::atomic<T>::operator=apparently kehrt ein T, so dass dieser Code dereferenziert ein ungültiger Zeiger, der auf einen temporären T Punkt verwendet:

Ich bin ganz sicher nicht, dass diese Codemuster gute Praxis sind, aber es ist sehr überraschend t o mir, dass std::atomic bricht sie. Ich erwarte immer operator= und Präfix operator++, um einen Verweis auf *this zurückzugeben.

Frage: Ist cppreference Recht, über die Rückgabetypen hier, und wenn ja, gibt es einen guten Grund dafür, dass std::atomic verhalten sich anders als integrierte Typen in dieser Hinsicht?

+0

Wenn 'operator =' ein 'T' zurückgibt, dann' & (v = 1) 'sollte nicht kompilieren, oder? –

+0

@ R.MartinhoFernandes: Weil es ein rvalue temporär ist? –

+0

Gibt es einen Lvalue zurück? Wenn nicht, dann wird das zweite ++ nicht kompilieren, so dass du zumindest vom Buggy-Verhalten gerettet wirst, wenn du das erwartet hast. – CashCow

Antwort

20

wenn operator++ eine Referenz zurückgegeben, wäre es ein Verweis auf std::atomic<T> nicht zu T gewesen, in dem Fall, dass Sie würde eine zusätzliche load tun, um den aktuellen Wert zu erhalten.

Imagine haben Sie ein DBMS bekommen und Sie benötigen ein 'autoincrement' Feld zu halten

Mit operator++T Neuabstimmung Sie diese

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

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

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

Jetzt operator++ kehren std::atomic<T>& In diesem Fall vorstellen, wenn Sie tun return ++current es wird zwei Dinge tun

  1. Atomare Rea d-Modifizieren-Schreiben
  2. Atomic Last

Sie sind zwei völlig unabhängige Operationen. Wenn andere Threads next dazwischen aufrufen, erhalten Sie einen falschen Wert für Ihr Autoinkrementfeld!

+4

+1.Kurz gesagt, weil Atomic (increment und return the new value) so viel nützlicher ist als (atomic increment) und (einen Verweis auf das atomare Objekt zurückgeben), meinen die Designer, dass es den etwas überraschenden Rückgabetyp rechtfertigt. –

+0

Bitte verunstalten Sie Ihre Antworten nicht mit einer Bearbeitung. Dies wurde zurückgesetzt. –

2

Nach [C++11: 29.6.5/32] und [C++11: 29.6.5/10], ja, cppreference.com ist in dieser Hinsicht richtig.

Ich bin nicht qualifiziert, Ihnen zu sagen, warum.

Verwandte Themen