2014-11-13 8 views
14

Zum Beispiel:Kann ein abgelaufener weak_ptr von einem nicht initialisierten unterschieden werden?

std::weak_ptr<int> wp1(std::make_shared<int>()); 
std::weak_ptr<int> wp2; 

assert(PointsToValidOrExpiredObject(wp1)); 
assert(!PointsToValidOrExpiredObject(wp2)); 

Ist eine solche Funktion möglich?

Anwendungsfall: Der Konstruktor einer Klasse nimmt std::weak_ptr<Foo> als Abhängigkeit. Die Übergabe eines abgelaufenen Objekts ist in Ordnung (kann in bestimmten Workflows vorkommen), aber das Übergeben von null bedeutet, dass der Programmierer etwas vergessen hat. Ich möchte dies als Teil der Parametervalidierung des Konstruktors testen.

+0

Haben Sie sich die Methode [expired() '] (http://en.cppreference.com/w/cpp/memory/weak_ptr/expired) angesehen? – Borgleader

+0

@Borgleader. Ja - leider trifft es für beide Fälle zu. – dlf

+1

Während es scheint, eine Antwort zu sein, könnte eine weniger magische Lösung darin bestehen, den schwachen Zeiger in einen Typ zu verpacken, der nur mit einem nicht leeren geteilten Zeiger konstruiert werden kann, und dies anstelle eines rohen schwachen Zeigers erfordert. –

Antwort

16

std::weak_ptr::owner_before kann zwischen schwachen Zeigern unterscheiden, die leer und abgelaufen sind.

template <typename T> 
bool PointsToValidOrExpiredObject(const std::weak_ptr<T>& w) { 
    return w.owner_before(std::weak_ptr<T>{}) || 
      std::weak_ptr<T>{}.owner_before(w); 
} 

Demo: Sie können deshalb PointsToValidOrExpiredObject als implementieren.

Regarding the original uncertainty I had about an expired weak_ptr still maintaining ownership: Ich bin jetzt sicher, dass die allgemeinen Bibliothek-weiten Thread-Sicherheitsanforderungen, dass ein abgelaufenes weak_ptr weiterhin das gleiche Eigentum hat. Andernfalls würde das Zerstören der letzten verbleibenden shared_ptr in Thread A den Zustand von einem/einigen/allen weak_ptr s, die das Eigentumsrecht mit dem in Frage stehenden shared_ptr teilen, sichtbar ändern müssen. Wenn Thread B gleichzeitig den Zustand eines solchen weak_ptr untersucht, dann würde ein Datenrennen durch die Bibliotheksimplementierung eingeführt werden, was im Allgemeinen verboten ist.

+0

Das scheint tatsächlich der Fall zu sein. Die Zeiger sind äquivalent "wenn sie den Besitz teilen oder beide leer sind", und es gibt nichts, das anzeigt, dass ein schwacher Zeiger leer wird (und aufhört, den Besitz zu teilen), wenn er abläuft. –

+1

Großartig! Ich musste die 'owner_before'-Dokumentation nachschlagen, um zu verstehen, was das bedeutet und warum es funktioniert. Für andere in der gleichen Situation: Sie können sich diese Funktion wie einen 'Operator dlf

Verwandte Themen