Đây là một sự kỳ quặc, nơi tôi không biết, nếu nó là với tiêu chuẩn C++, với trình biên dịch của tôi (G ++ phiên bản 4.6.3 trên Ubuntu 12.04, là dài hạn mới nhất hỗ trợ phiên bản của Ubuntu) hoặc với tôi, những người không hiểu ;-)std :: hoán đổi lạ với G ++
các mã trong câu hỏi là đơn giản như sau:
#include <algorithm> // for std::swap
void f(void)
{
class MyClass { };
MyClass aa, bb;
std::swap(aa, bb); // doesn't compile
}
Khi cố gắng để biên dịch với G ++, trình biên dịch mang lại như sau thông báo lỗi:
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])
Kết quả đáng ngạc nhiên là, mà chỉ cần di chuyển các định nghĩa lớp ra khỏi chức năng làm cho mã biên dịch tốt:
#include <algorithm> // for std::swap
class MyClass { };
void f(void)
{
MyClass aa, bb;
std::swap(aa, bb); // compiles fine!
}
Vậy là nó, đó std :: swap() là không được phép làm việc trên lớp, đó là riêng tư cho các chức năng? Hoặc đây có phải là lỗi với G ++, có thể là phiên bản cụ thể của G ++ tôi đang sử dụng không?
Thậm chí khó hiểu là, rằng sau đây không hoạt động trở lại, mặc dù MyListClass cũng là tư nhân (nhưng kéo dài một lớp "chính thức", mà có thể là một thực hiện cụ thể của swap() tồn tại) hơn:
#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!
}
Nhưng chỉ cần thay đổi từ các đối tượng thành con trỏ và biên dịch lại không thành công:
#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!
}
Tất nhiên, trong ứng dụng thực tế, các lớp học phức tạp hơn; Tôi đã đơn giản hóa mã càng nhiều càng tốt để vẫn tái tạo vấn đề.
Theo [Apache wiki] (http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport), GCC hỗ trợ điều này từ 4.5, do đó, sẽ đủ để thêm tùy chọn '-std = c + + 0x'. – Angew
Cảm ơn bạn rất nhiều vì câu trả lời của bạn! Thêm -std = C++ 0x làm cho mọi thứ biên dịch tốt ngay cả với các lớp địa phương. Wow, tôi không biết về sự không tương thích với các lớp và các mẫu cục bộ trong các tiêu chuẩn C++ cũ hơn. –