Lo standard non richiede che questo si compili su nessuna toolchain!
Per prima cosa ricorda che vector<bool>
è strano e la sottoscrizione ti dà un oggetto temporaneo di un tipo proxy chiamato std::vector<bool>::reference
, piuttosto che un effettivo bool&
.
Il messaggio di errore indica che non è possibile associare questo temporaneo a un const
riferimento non di valore nell'implementazione generica template <typename T> std::swap(T& lhs, T& rhs)
.
Estensioni!
Tuttavia, risulta che libstdc ++ definisce un sovraccarico per std::swap(std::vector<bool>::reference, std::vector<bool>::reference)
, ma questa è un'estensione dello standard (o, se è presente, non riesco a trovare alcuna prova).
Anche libc ++ fa questo .
Immagino che l'implementazione stdlib di Visual Studio, che stai ancora usando, non lo fa , ma poi per aggiungere un insulto a un infortunio puoi associare i temporali ai riferimenti lvalue in VS (a meno che tu non stia usando la modalità di conformità), quindi il la funzione standard, "generica", std::swap
funziona fino a quando non si sostituisce il compilatore VS al compilatore Clang più rigoroso.
Di conseguenza, hai fatto affidamento sulle estensioni su tutte e tre le toolchain per le quali ha funzionato per te e la combinazione Clang su Windows è l'unica che mostra effettivamente una rigorosa conformità.
(Secondo me, queste tre toolchain avrebbero dovuto diagnosticare questo, quindi non hai spedito codice non portatile per tutto il tempo. 😊)
E adesso?
Potrebbe essere allettante aggiungere la tua specializzazione di std::swap
e std::vector<bool>::reference
, ma non ti è permesso farlo per i tipi standard; in effetti, sarebbe in conflitto con i sovraccarichi che libstdc ++ e libc ++ hanno scelto di aggiungere come estensioni.
Quindi, per essere portatile e conforme, è necessario modificare il codice .
Forse un buon vecchio stile:
const bool temp = vb[0];
vb[0] = vb[1];
vb[1] = temp;
Oppure utilizza la speciale funzione di membro statico che fa esattamente quello che volevi :
std::vector<bool>::swap(vb[0], vb[1]);
Anche ortografico come segue:
vb.swap(vb[0], vb[1]);
operator[]
un valore? e puòstd::swap
operare su valori e valori x?