2012-11-05 10 views
13

Według this prefiksu std::atomic<T>::operator++ zwraca T, więc ten kod zwiększa tylko v raz:Czy std :: atomic :: operator ++ naprawdę zwraca wartość?

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

Również std::atomic<T>::operator=apparently Zwraca T, więc ten kod dereferences nieprawidłowy wskaźnik, który używany aby wskazać tymczasowe T:

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

Ja na pewno nie sugeruję, że te wzorce kodowe są dobrą praktyką, jednak jest to bardzo zaskakujące o mnie, że je łamie. Zawsze oczekuję, że operator= i prefiks operator++ zwrócą referencję do *this.

Pytanie: Czy cppreference prawo o rodzajach tu wrócić, a jeśli tak, to czy istnieje dobry powód konieczności std::atomic zachowują się inaczej niż wbudowanych typów w tym zakresie?

+0

Jeśli 'operator =' zwraca 'T', to' i (v = 1) 'nie powinno się nawet kompilować, prawda? –

+0

@ R.MartinhoFernandes: Ponieważ jest to tymczasowa rura? –

+0

Czy zwraca wartość l? Jeśli nie, to drugie ++ nie skompiluje się, więc przynajmniej uratujesz się od błędnego zachowania, jeśli spodziewałeś się, że to się rozwinie. – CashCow

Odpowiedz

20

jeśli operator++ powrócił odniesienie, byłoby odniesienie do std::atomic<T> nie T w takim przypadku trzeba by zrobić dodatkowe load uzyskać bieżącą wartość.

Wyobraź sobie, że masz DBMS i trzeba utrzymać „autoIncrement” pole

Z operator++ przestrajania T można to zrobić

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

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

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

Teraz wyobraź operator++ powraca std::atomic<T>& W takim przypadku, gdy robisz return ++current zrobi dwie rzeczy:

  1. Atomowy rea d-modyfikacja zapisu
  2. obciążenia Atomowej

Są to dwa całkowicie niezależne operacje. Jeśli inny wątek zadzwoni next pomiędzy otrzymasz błędną wartość dla twojego pola autoreklalizacji!

+4

+1.W skrócie, ponieważ atomic (inkrementacja i zwrócenie nowej wartości) jest o wiele bardziej użyteczna niż (przyrost atomowy) i (zwraca odniesienie do obiektu atomowego), co projektanci uważają za uzasadniający nieco zaskakujący typ powrotu. –

+0

Proszę nie zamazywać swoich odpowiedzi za pomocą edycji. Zostało to wycofane. –

2

Zgodnie z [C++11: 29.6.5/32] i [C++11: 29.6.5/10], tak, cppreference.com ma poprawne pod tym względem.

Nie mam kwalifikacji, aby ci powiedzieć, dlaczego.

Powiązane problemy