Có vẻ như (2) ( đứng tự do swaptrong cùng một không gian tên nơi khai báo lớp do người dùng xác định ) là cách được phép duy nhất để cung cấp swapcho một lớp do người dùng xác định, bởi vì việc thêm khai báo vào không gian tên stdnói chung là một hành vi không xác định. Mở rộng không gian tên std (cppreference.com) :
Việc thêm khai báo hoặc định nghĩa vào không gian tên stdhoặc bất kỳ không gian tên nào được lồng trong đó là hành vi không xác định std, với một vài ngoại lệ được lưu ý dưới đây
Và swapkhông được biểu thị là một trong những trường hợp ngoại lệ. Vì vậy, thêm swapquá tải của riêng bạn vàostd không gian tên là một hành vi không xác định.
Người ta cũng nói rằng thư viện chuẩn sử dụng một lệnh gọi không đủ tiêu chuẩn tới swaphàm để gọi do người dùng xác định swapcho một lớp người dùng nếu người dùng đó xác địnhswap được cung cấp.
Có thể thay đổi (cppreference.com) :
Nhiều hàm thư viện tiêu chuẩn (ví dụ, nhiều thuật toán) mong đợi các đối số của chúng đáp ứng Swappable , có nghĩa là bất kỳ lúc nào thư viện chuẩn thực hiện hoán đổi, nó sử dụng tương đương vớiusing std::swap; swap(t, u); .
hoán đổi (www.cplusplus.com) :
Nhiều thành phần của thư viện chuẩn (trong std) gọi swaptrong một không đủ tiêu chuẩn theo cách để cho phép quá tải tùy chỉnh với nhiều loại phi cơ bản được gọi là thay vì phiên bản generic này: quá tải Tuỳ chỉnh của swaptuyên bố trong không gian tên tương tự như các loại mà họ được cung cấp được chọn thông qua tra cứu phụ thuộc vào đối số trên phiên bản chung này.
Nhưng lưu ý rằng việc sử dụng trực tiếp std::swaphàm cho lớp do người dùng xác định sẽ gọi phiên bản chung std::swapthay vì người dùng xác định swap:
my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap
Vì vậy, bạn nên gọi swaphàm trong mã người dùng theo cách giống như cách thực hiện trong thư viện chuẩn:
my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.