La norme n'exige pas cela pour compiler sur n'importe quelle chaîne d' outils!
Rappelez-vous d'abord que vector<bool>
c'est bizarre et que l'indexation vous donne un objet temporaire d'un type proxy appelé std::vector<bool>::reference
, plutôt qu'un réel bool&
.
Le message d'erreur vous indique qu'il ne peut pas lier ce temporaire à une const
référence non lvalue dans l' template <typename T> std::swap(T& lhs, T& rhs)
implémentation générique .
Extensions!
Cependant, il s'avère que libstdc ++ définit une surcharge pour std::swap(std::vector<bool>::reference, std::vector<bool>::reference)
, mais c'est une extension de la norme (ou, si elle est là-dedans, je ne trouve aucune preuve pour cela).
libc ++ fait aussi cela .
Je suppose que l'implémentation stdlib de Visual Studio, que vous utilisez toujours, ne fonctionne pas , mais pour ajouter une insulte à une blessure, vous pouvez lier des références temporaires à des références de valeur dans VS (sauf si vous utilisez le mode de conformité), de sorte que le la fonction standard, "générique", std::swap
fonctionne jusqu'à ce que vous remplaciez le compilateur VS par le compilateur Clang plus strict.
En conséquence, vous vous êtes appuyé sur des extensions sur les trois chaînes d'outils pour lesquelles cela a fonctionné pour vous, et la combinaison Clang sur Windows est la seule à afficher une stricte conformité.
(À mon avis, ces trois chaînes d'outils auraient dû diagnostiquer cela afin que vous n'ayez pas expédié de code non portable pendant tout ce temps. 😊)
Et maintenant?
Il peut être tentant d'ajouter votre propre spécialisation de std::swap
et std::vector<bool>::reference
, mais vous n'êtes pas autorisé à le faire pour les types standard; en effet, cela entrerait en conflit avec les surcharges que libstdc ++ et libc ++ ont choisi d'ajouter en tant qu'extensions.
Donc, pour être portable et conforme, vous devez changer votre code .
Peut-être un bon vieux jeu:
const bool temp = vb[0];
vb[0] = vb[1];
vb[1] = temp;
Ou utilisez la fonction membre statique spéciale qui fait exactement ce que vous vouliez :
std::vector<bool>::swap(vb[0], vb[1]);
Également épelable comme suit:
vb.swap(vb[0], vb[1]);
operator[]
une valeur l? et peutstd::swap
fonctionner sur rvalues et xvalues?