To jest dziwactwo, gdzie nie wiem, jeśli jest ze standardem C++, z moim kompilatorem (G ++ wersja 4.6.3 na Ubuntu 12.04, który jest najnowszym długoterminowym wsparcie wersja Ubuntu) lub ze mną, kto nie rozumie ;-)std :: zamień dziwność z G ++
Kod w pytaniu jest tak proste, jak następuje:
#include <algorithm> // for std::swap
void f(void)
{
class MyClass { };
MyClass aa, bb;
std::swap(aa, bb); // doesn't compile
}
Kiedy próbuje skompilować z g ++, kompilator daje następujące komunikat o błędzie:
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])
Zaskakujący wynik jest, że po prostu się definicję klasy z funkcji sprawia, że kod skompilować grzywny:
#include <algorithm> // for std::swap
class MyClass { };
void f(void)
{
MyClass aa, bb;
std::swap(aa, bb); // compiles fine!
}
Więc jest to, że std :: swap() nie ma do pracy na zajęciach, które są prywatny do funkcji? Czy jest to błąd w G ++, może konkretnej wersji G ++ używam?
Jeszcze bardziej zastanawiające jest, że następujący działa ponownie, mimo MyListClass jest także prywatny (ale rozciąga się „oficjalnego” klasę, do której być może istnieje konkretna realizacja transakcji 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!
}
Ale po prostu przełącz się z obiektów na wskaźniki, a kompilacja ponownie się zawiesza:
#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!
}
Oczywiście w moim prawdziwym zastosowaniu klasy są bardziej złożone; Uprośniłem kod tak bardzo, jak to możliwe, aby nadal odtwarzać problem.
Według [wiki Apache] (http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport), GCC obsługuje to od wersji 4.5, więc powinno wystarczyć dodanie opcji '-std = c + + 0x'. – Angew
Dziękuję bardzo za odpowiedzi! Dodanie opcji -std = C++ 0x sprawia, że kompilacja jest dobra nawet w przypadku klas lokalnych. Wow, nie wiedziałem o niekompatybilności z lokalnymi klasami i szablonami w starszych standardach C++. –