Có vẻ như (2) ( đứng tự do swap
trong 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 swap
cho 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 std
nó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 std
hoặ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à swap
không được biểu thị là một trong những trường hợp ngoại lệ. Vì vậy, thêm swap
quá 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 swap
hàm để gọi do người dùng xác định swap
cho 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 swap
trong 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 swap
tuyê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::swap
hàm cho lớp do người dùng xác định sẽ gọi phiên bản chung std::swap
thay 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 swap
hà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.