Um mein Problem zu demonstrieren, betrachten Sie dieses einfache Programm, das nicht kompiliert:
%Vor% Mit der aktuellen Version von boost (1.52) gibt Visual Studio 2012 den Fehler zurück:
cannot access private member declared in class 'boost::noncopyable_::noncopyable
.
Der Operator [] für std :: unordered_map gibt einen Verweis auf das Element an dem angegebenen Schlüssel zurück, der auf den ersten Blick so aussieht, als ob er funktionieren sollte - ich habe nach einem Verweis auf das Element gefragt, nicht nach einer Kopie davon .
Mein Verständnis des Problems ist das (was falsch sein könnte, da ich C ++ schon lange nicht mehr benutzt habe). Wenn der Schlüssel nicht gefunden wird, erstellt unordered_map ein neues Element und gibt einen Verweis auf das neue Element zurück. boost :: noncopyable definiert einen (privaten) Kopierkonstruktor, aber keinen Bewegungskonstruktor, und daher wird vom Konstruktor kein Bewegungskonstruktor generiert. In seinem Operator [] verwendet std :: unordered_map std :: move, aber da boost :: noncopyable keinen move-Konstruktor definiert, greift es auf den copy-Konstruktor zurück. Da der Kopierkonstruktor privat ist, schlägt die Kompilierung fehl.
Was diesen Beitrag veranlasst hat, ist, dass ich versuche, eine unordered_map von boost :: signal2 :: signal zu erstellen, die von boost :: noncopyable erbt. Kann ich die Boost-Bibliothek nicht hacken, gibt es eine einfache Problemumgehung? Das Signal in einem unique_ptr zu verpacken ist eine Option, aber es scheint mir, dass ich hier etwas falsch machen könnte.
Ich habe vielleicht zu früh gepostet! Es scheint unmöglich, eine Unterklasse von boost :: noncopyable zu unordered_map hinzuzufügen. Insert, operator [] und emplace verwenden entweder einen Kopierkonstruktor (der privat ist) oder einen Verschiebevorgang (der für boost :: noncopyable nicht existiert). Das scheint mir eine große Einschränkung zu sein. Ist es sogar möglich, eine unordered_map zu erstellen, die boost :: nicht kopierbare Objekte enthält? Ich bin explizit nicht versuche sie zu kopieren - ich möchte, dass sie ihre gesamte Lebensdauer in der unordered_map verbringen.
Es ist nicht unmöglich, eine Unterklasse von boost::noncopyable
in unordered_map
zu verwenden, Sie müssen einfach einen Bewegungskonstruktor für Ihren Typ definieren. C ++ erstellt keinen Standard-Move-Konstruktor, wenn Sie ein eigenes Kopierkonstrukt erstellt haben (was boost::noncopyable
tut). Wenn es den Standardbewegungskonstruktor definiert, würde es auch versuchen, den Kopierkonstruktor des Elternteils aufzurufen, der privat ist. Daher müssen Sie einen Verschiebungskonstruktor definieren, der nicht versucht, den Kopierkonstruktor von boost::noncopyable
aufzurufen. Zum Beispiel funktioniert das gut:
Das ist wahrscheinlich nicht genau das, wonach du suchst, aber ich dachte, ich würde es da draußen rausschmeißen. Beachtenswert ist der second
-Wert des zurückgegebenen Paares von emplace()
, was darauf hinweist, dass der zweite Aufruf nicht ein neues Element einfügt oder das übergeordnete Element kopiert.
Auch hier weiß ich nicht, ob das näher an dem ist, was Sie wollen, aber einen Versuch wert. Ich habe wahrscheinlich etwas falsch gemacht, da ich mit der C ++ 11-Standardbibliothek nicht so vertraut bin wie andere. Tut mir leid, wenn das so ist.
Beachten Sie schließlich, dass nicht versucht, die Anforderung des OP, operator []()
für insert + access zu verwenden, anzusprechen. Es versucht vielmehr, einfach eine boost::noncopyable
Ableitung in eine unordered_map<>
konstruiert zu bekommen. Um auf Sie zugreifen zu können, benötigen Sie wahrscheinlich eine Kombination aus dem Folgenden und einem anfänglichen find()
, um festzustellen, ob das Tag ursprünglich existiert.
Wie auch immer ...
%Vor%Ausgabe
%Vor%