Wenn das Ziel ist konstante Zeit für das Nachschlagen, ich glaube nicht, dass gibt es eine Lösung. std::unordered_set<std::unique_ptr<MyClass>>::find
erfordert ein std::unique_ptr<MyClass>
als Argument. Sie müssen entweder den Container ändern oder den enthaltenen Typ ändern.
Eine Möglichkeit könnte sein, ersetzen std::unique_ptr
mit std::shared_ptr
, und dem Rest des so-Code ändern, dass alle MyClass
in eine shared_ptr setzen, sobald sie erstellt werden, und werden nur durch gemeinsamen Zeiger manipulieren. Logischerweise das ist wahrscheinlich sowieso kohärenter: unique_ptr
ziemlich viel impliziert (durch seinen Namen, sowie seine Semantik), dass dort sind keine anderen Zeiger auf das Objekt. Auf der anderen Seite können Sie Shared_ptr nicht verwenden, wenn z. MyClass
hat Zeiger auf andere MyClass
, die einen Zyklus aufbauen können.
Andernfalls, wenn Sie O (lg n) Zugang annehmen können, anstatt ständigen Zugang (die Differenz in der Regel nicht bemerkbar macht werden, bis die Tische ziemlich groß sind), können Sie ein std::vector<MyClass>
, mit std::lower_bound
verwenden behalte es sortiert. Im Gegensatz zu std::unordered_set<>::find
, std::lower_bound
bedeutet nicht erfordern, dass der Zielwert denselben Typ hat wie der value_type
der Sequenz; alles, was Sie tun müssen, ist , um sicherzustellen, dass sie vergleichbar sind, etwa durch ein Compare
Objekt entlang der Linien der Bereitstellung:
class MyClassPtrCompare
{
std::less<MyClass const*> cmp;
public:
bool operator()(std::unique_ptr<MyClass> const& lhs,
std::unique_ptr<MyClass> const& rhs) const
{
return cmp(lhs.get(), rhs.get());
}
bool operator()(MyClass const* lhs,
std::unique_ptr<MyClass> const& rhs) const
{
return cmp(lhs, rhs.get());
}
bool operator()(std::unique_ptr<MyClass> const& lhs,
MyClass const* rhs) const
{
return cmp(lhs.get(), rhs);
}
bool operator()(MyClass const* lhs,
MyClass const* rhs) const
{
return cmp(lhs, rhs);
}
};
Insertion eine Anzahl von Bewegungen beinhalten kann, aber ein std::unique_ptr
sollte bewegen ziemlich billig sein und die verbesserte Lokalität dieser Lösung könnte die zusätzlichen Laufzeitkosten, die ansonsten auferlegt werden, kompensieren.
Dank. Ich muss nichts bewegen oder kopieren, also ist unique_ptr in Ordnung. Ich muss nur den Anrufer einen rohen Zeiger geben lassen, und ich muss überprüfen, ob ein passender unique_ptr in der Menge vorhanden ist. – cfa45ca55111016ee9269f0a52e771
'unique_ptr' ist offensichtlich nicht das, was Sie brauchen, da Sie eindeutig andere Zeiger auf das Objekt haben. –
Der Besitzer des unique_ptr ist der einzige Besitzer des Speichers, und alle anderen enthalten nur Referenzen. Ich könnte shared :: ptr überall im owner und weak_ptr verwenden, aber dann wird jedes Objekt von einem einzigen shared_ptr referenziert. Ich brauche das Teilen nicht, nur einen einzigen Besitzer – cfa45ca55111016ee9269f0a52e771