Questa è una stranezza, dove non so, se è con lo standard C++, con il mio compilatore (versione G ++ 4.6.3 su Ubuntu 12.04, che è l'ultima a lungo termine versione supporto di Ubuntu), o con me, che non capisce ;-)std :: swap stranezza con G ++
il codice in questione è tanto semplice quanto segue:
#include <algorithm> // for std::swap
void f(void)
{
class MyClass { };
MyClass aa, bb;
std::swap(aa, bb); // doesn't compile
}
Quando si cerca di compilare con G ++, il compilatore produce il seguente messaggio di errore:
test.cpp: In function ‘void f()’:
test.cpp:6:21: error: no matching function for call to ‘swap(f()::MyClass&, f()::MyClass&)’
test.cpp:6:21: note: candidates are:
/usr/include/c++/4.6/bits/move.h:122:5: note: template<class _Tp> void std::swap(_Tp&, _Tp&)
/usr/include/c++/4.6/bits/move.h:136:5: note: template<class _Tp, long unsigned int _Nm> void std::swap(_Tp (&)[_Nm], _Tp (&)[_Nm])
Il risultato sorprendente è che semplicemente spostando la definizione della classe di funzione fa si che il codice compilato bene:
#include <algorithm> // for std::swap
class MyClass { };
void f(void)
{
MyClass aa, bb;
std::swap(aa, bb); // compiles fine!
}
Così è, che std :: swap() non dovrebbe lavorare sulle classi, che sono privato di funzioni? O è un bug con G ++, forse la versione specifica di G ++ che sto usando?
Ancora più sconcertante è che il seguente funziona ancora una volta, nonostante MyListClass è anche privato (ma si estende una classe di "ufficiale", per la quale forse esiste una specifica implementazione di swap()):
#include <algorithm> // for std::swap
#include <list> // for std::list
void g(void)
{
class MyListClass : public std::list<int> { };
MyListClass aa, bb;
std::swap(aa, bb); // compiles fine!
}
ma basta cambiare da oggetti a puntatori, e la compilazione fallisce di nuovo:
#include <algorithm> // for std::swap
#include <list> // for std::list
void g(void)
{
class MyListClass : public std::list<int> { };
MyListClass aa, bb;
MyListClass* aap = &aa;
MyListClass* bbp = &bb;
std::swap(aap, bbp); // doesn't compile!
}
Naturalmente, nella mia applicazione reale le classi sono più complesse; Ho semplificato il codice il più possibile per riprodurre ancora il problema.
Secondo [il wiki Apache] (http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport), GCC supporta questo dal 4.5, quindi dovrebbe essere sufficiente aggiungere l'opzione '-std = c + + 0x'. – Angew
Grazie mille per le vostre risposte! Aggiungere -std = C++ 0x rende le cose ben compilabili anche con le classi locali. Wow, non sapevo dell'incompatibilità con classi e template locali nei vecchi standard C++. –