2011-01-24 27 views
20

Trong khi thực hành một số C++, tôi đã cố gắng tìm hiểu và chấp nhận thành ngữ sao chép-hoán đổi sau lời giải thích kỹ lưỡng này về câu hỏi này: the Copy-Swap Idiom.những gì hiện `bằng cách sử dụng std :: swap` bên trong cơ thể của một phương pháp thực hiện phương pháp lớp có nghĩa là gì?

Nhưng tôi tìm thấy một số mã tôi chưa từng thấy: using std::swap; // allow ADL trong ví dụ này

class dumb_array 
{ 
public: 
    // ... 

    void swap(dumb_array& pOther) // nothrow 
    { 
     using std::swap; // allow ADL /* <===== THE LINE I DONT UNDERSTAND */ 

     swap(mSize, pOther.mSize); // with the internal members swapped, 
     swap(mArray, pOther.mArray); // *this and pOther are effectively swapped 
    } 
}; 
  1. using std::swap; nghĩa bên trong cơ thể của một hàm thực hiện?
  2. ADL là gì?
+1

[Câu trả lời của MSalter] (http://stackoverflow.com/a/4782809/464581) là IMHO rõ ràng là câu trả lời toàn diện hơn, vì ông giải thích về ADL (đó là toàn bộ lý do để thực hiện 'sử dụng' tại đây) . Tôi nghĩ bạn nên chọn giải pháp đó. –

Trả lời

52

Cơ chế này thường được sử dụng trong mã templated, ví dụ: template <typename Value> class Foo.

Bây giờ câu hỏi được trao đổi để sử dụng. std::swap<Value> sẽ hoạt động nhưng có thể không lý tưởng. Có khả năng xảy ra tình trạng quá tải tốt hơn là swap đối với loại Value, nhưng trong đó không gian tên nào sẽ là? Nó gần như chắc chắn không phải trong std:: (vì đó là bất hợp pháp), nhưng rất có thể trong không gian tên của Value. Có khả năng, nhưng xa nhất định.

Trong trường hợp đó, swap(myValue, anotherValue) sẽ giúp bạn trao đổi "tốt nhất" có thể. Tra cứu phụ thuộc đối tượng sẽ tìm thấy bất kỳ trao đổi nào trong không gian tên nơi Value xuất phát từ đó. Nếu không, cú pháp chỉ thị using sẽ xuất hiện và std::swap<Value> sẽ được khởi tạo và sử dụng.

Trong mã của bạn, mSize có thể là một loại tích phân và mArray một con trỏ. Không có một không gian tên liên quan, và std::swap là với tối ưu hóa chắc chắn 99,9% cho họ anyway. Do đó, tuyên bố using std::swap; dường như vô dụng ở đây.

+5

Tôi tin rằng nó là khá hợp pháp để cung cấp các chuyên ngành của các chức năng tiêu chuẩn templated bên trong không gian tên 'std'. §17.4.3.1/1 "Một chương trình có thể thêm chuyên môn mẫu cho bất kỳ mẫu thư viện chuẩn nào vào không gian tên std. Một chuyên ngành (đầy đủ hoặc một phần) của mẫu thư viện chuẩn dẫn đến hành vi không xác định trừ khi khai báo phụ thuộc vào tên do người dùng định nghĩa liên kết bên ngoài và trừ khi chuyên môn đáp ứng các yêu cầu thư viện chuẩn cho mẫu ban đầu "Điều đó nói rằng, không phổ biến để thực hiện các chuyên môn' swap' trong không gian tên 'std'. –

+7

@dribeas: thực sự nó là hợp pháp để chuyên 'std :: swap', và nếu nghi ngờ về người dùng của bạn, bạn có lẽ nên chuyên' std :: swap' * và * cung cấp một 'swap' trong không gian tên của riêng bạn được tìm thấy bởi ADL. Nhưng có giới hạn để chuyên 'std :: swap', kẻ giết người là bạn không thể * một phần * chuyên nó, bởi vì nó là một mẫu chức năng, và vì vậy nếu bạn đã viết một mẫu lớp (giống như một vùng chứa mới) , bạn không thể chuyên 'std :: swap' cho nó, và do đó bạn phải đi theo tuyến đường ADL. MSalters là chính xác trong những gì ông nói, mặc dù: bạn không thể quá tải 'std :: swap', chỉ chuyên. –

10

Từ khóa using có hiệu ứng phạm vi.

Điều này có nghĩa là std::swap có thể được gọi là swap trong phạm vi từ khóa using.

+16

và tôi tin rằng ADL trong ngữ cảnh này chỉ có nghĩa là "tra cứu phụ thuộc đối số". Điều đó cho phép mã sử dụng "hoán đổi" có hoặc không có hàm hoán đổi cục bộ được xác định. Nếu một địa phương không tồn tại, sau đó std :: trao đổi được sử dụng – vmpstr

+3

@ vmpstr: Nếu bạn đặt đó như là một câu trả lời riêng biệt bạn nhận được 10 danh tiếng chỉ vì tôi bỏ phiếu nó lên. – Benoit

+4

Đây là một câu trả lời vô dụng phải trung thực. Nó không giải thích sự tương tác của 'using std :: swap' và ADL. Câu trả lời của MSalters phải là câu trả lời được chấp nhận. –

-2

Câu trả lời ngắn

using std::swap; // allow ADL /* <===== THE LINE I DONT UNDERSTAND */ 

cần thiết để tránh cuộc gọi đệ quy để hoán đổi thành viên. Hoán đổi thành viên vô hiệu hóa ADL.

Các vấn đề liên quan