Der Standard verlangt dies nicht, um in irgendeiner Toolchain zu kompilieren !
Wenn Sie sich zunächst daran erinnern, dass dies vector<bool>
seltsam ist und wenn Sie es abonnieren, erhalten Sie ein temporäres Objekt eines Proxy-Typs namens std::vector<bool>::reference
und kein tatsächliches bool&
.
Die Fehlermeldung weist darauf hin, dass diese temporäre const
Datei nicht an eine nicht wertvolle Referenz in der generischen template <typename T> std::swap(T& lhs, T& rhs)
Implementierung gebunden werden kann .
Erweiterungen!
Es stellt sich jedoch heraus, dass libstdc ++ eine Überladung für definiertstd::swap(std::vector<bool>::reference, std::vector<bool>::reference)
, dies ist jedoch eine Erweiterung des Standards (oder, falls vorhanden, kann ich keine Beweise dafür finden).
libc ++ macht das auch .
Ich würde vermuten, dass die Visual Studio stdlib-Implementierung, die Sie noch verwenden, dies nicht tut , aber um die Verletzung zusätzlich zu beleidigen, können Sie temporäre Werte an l-Wert-Referenzen in VS binden (es sei denn, Sie verwenden den Konformitätsmodus) Die Standardfunktion "generic" std::swap
funktioniert so lange, bis Sie den VS-Compiler durch den strengeren Clang-Compiler ersetzen.
Infolgedessen haben Sie sich bei allen drei Toolchains, für die es für Sie funktioniert hat, auf Erweiterungen verlassen, und die Clang on Windows-Kombination ist die einzige, die tatsächlich strikte Konformität aufweist.
(Meiner Meinung nach hätten diese drei Toolchains dies diagnostizieren sollen, damit Sie nicht die ganze Zeit nicht portierbaren Code ausgeliefert haben. 😊)
Was jetzt?
Es mag verlockend sein, eine eigene Spezialisierung von std::swap
und hinzuzufügen std::vector<bool>::reference
, aber Sie dürfen dies nicht für Standardtypen tun. In der Tat würde dies im Widerspruch zu den Überladungen stehen, die libstdc ++ und libc ++ als Erweiterungen hinzugefügt haben.
Um portabel und kompatibel zu sein, sollten Sie Ihren Code ändern .
Vielleicht ein guter altmodischer:
const bool temp = vb[0];
vb[0] = vb[1];
vb[1] = temp;
Oder nutzen Sie die spezielle statische Elementfunktion, die genau das tut, was Sie wollten :
std::vector<bool>::swap(vb[0], vb[1]);
Auch wie folgt buchstabierbar:
vb.swap(vb[0], vb[1]);
operator[]
eines Wertes? und kannstd::swap
mit rWerten und xWerten arbeiten?