2010-10-14 3 views
11

In C++ 0x (n3126) können Smartpointer sowohl relational als auch auf Gleichheit verglichen werden. Die Art und Weise, wie dies gemacht wird, scheint mir jedoch widersprüchlich zu sein.C++ 0x Smart Pointer Vergleiche: Inkonsistent, was ist der Grund?

template <typename T, typename U> 
bool operator<(const shared_ptr<T>& a, const shared_ptr<T>& b) 
{ 
    return std::less<void*>()(a.get(), b.get()); 
} 

Verwendung std::less Totalordnung mit Bezug auf Zeigerwerte, im Gegensatz zu einem Vanille- relational pointer Vergleich, der nicht näher bezeichnet ist, sieht vor:

beispielsweise operator<shared_ptr definiert äquivalent.

definiert jedoch unique_ptr den gleichen Betreiber wie:

template <typename T1, typename D1, typename T2, typename D2> 
bool operator<(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b) 
{ 
    return a.get() < b.get(); 
} 

Es definiert auch die anderen relationalen Operatoren in ähnlicher Weise.


Warum die Änderung der Methode und "Vollständigkeit"? Das heißt, warum verwendet shared_ptrstd::less, während unique_ptr die integrierte operator< verwendet? Und warum stellt shared_ptr nicht auch die anderen relationalen Operatoren zur Verfügung, wie unique_ptr?

Ich kann verstehen, die Gründe jeder Wahl:

  • in Bezug auf Verfahren: es repräsentiert einen Zeiger so verwenden Sie einfach die integrierten in Zeiger Operatoren, im Vergleich zu ihm in einem assoziativen Container verwendbar sein muss, so bieten Gesamtbestellung (wie ein Vanilla-Pointer würde mit dem Standard std::less Prädikat Vorlage Argument)
  • in Bezug auf die Vollständigkeit: es stellt einen Zeiger so bieten die gleichen Vergleiche wie ein Zeiger, im Gegensatz zu es ist ein Klassen-Typ und muss nur sein weniger als vergleichbar in einem assoziativen Container verwendet werden, so stellen Sie nur diese Anforderung

Aber ich sehe nicht, warum die Wahl je nach dem Smart-Zeigertyp ändert. Was vermisse ich?


Bonus/bezogen werden: std::shared_ptr scheint von boost::shared_ptr gefolgt zu sein, und dieser lässt die anderen relationalen Operatoren "by design" (und std::shared_ptr tut dies auch). Warum ist das?

Antwort

12

Dies war ein Fehler in den Entwürfen von C++ 11; Ein Fehlerbericht wurde geöffnet, um die std::unique_ptr relationalen Operatorüberladungen zu ändern, um std::less zu verwenden: siehe LWG Defect 1297.

Dies wurde rechtzeitig für die endgültige C++ 11 Spezifikation festgelegt. C++ 11 §20.7.1.4 [unique.ptr.special]/5 gibt an, dass die Überlast operator<:

Returns:less<CT>()(x.get(), y.get())

wo xy und die beiden Operanden der ARE Operator und CT ist der gemeinsame Typ der beiden Zeiger (da Zeiger auf verschiedene Typen, zB mit verschiedenen cv-Qualifikationen, verglichen werden können).

+0

Ah, ich sollte zuerst dort suchen. :) Das beantwortet definitiv die Änderung der Methode, aber weißt du, warum 'shared_ptr' nicht alle anderen relationalen Operatoren liefert? – GManNickG

+0

@GMan: Ich denke, das könnte ein Fehler sein. Sie sind in 20.9 in der '' Synopsis aufgeführt, aber sie sind nicht tatsächlich in 20.9.11.2.7 ... –

+0

@James: Oh, guter Ruf. Ich war nur auf die 'shared_ptr'-Sektion beschränkt. Nun, das löst das, denke ich. (Sie sollten das wirklich aufräumen.) Danke. – GManNickG