2010-10-14 14 views
11

Trong C++ 0x (n3126), con trỏ thông minh có thể được so sánh, cả về mặt quan hệ lẫn bình đẳng. Tuy nhiên, cách này được thực hiện có vẻ không phù hợp với tôi.C++ So sánh con trỏ thông minh 0x: Không nhất quán, lý do cơ bản là gì?

Ví dụ, shared_ptr định nghĩa operator< tương đương với:

template <typename T, typename U> 
bool operator<(const shared_ptr<T>& a, const shared_ptr<T>& b) 
{ 
    return std::less<void*>()(a.get(), b.get()); 
} 

Sử dụng std::less cung cấp tổng trật tự đối với các giá trị con trỏ với, không giống như một vani quan hệ so sánh con trỏ, đó là không xác định.

Tuy nhiên, unique_ptr xác định người điều khiển tương tự như:

template <typename T1, typename D1, typename T2, typename D2> 
bool operator<(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b) 
{ 
    return a.get() < b.get(); 
} 

Nó cũng định nghĩa các toán tử quan hệ khác trong thời trang tương tự.


Tại sao thay đổi phương thức và "đầy đủ"? Đó là, tại sao shared_ptr sử dụng std::less trong khi unique_ptr sử dụng tích hợp sẵn operator<? Và tại sao không shared_ptr cũng cung cấp các toán tử quan hệ khác, như unique_ptr?

tôi có thể hiểu được lý do đằng sau một trong hai lựa chọn:

  • liên quan đến phương pháp với: nó đại diện cho một con trỏ vì vậy chỉ cần sử dụng các toán tử con trỏ built-in, so với nó cần phải được sử dụng trong một container kết hợp để cung cấp tổng số thứ tự (giống như một con trỏ vani sẽ nhận được đối số mẫu mặc định std::less)
  • liên quan đến tính đầy đủ: nó đại diện cho con trỏ để cung cấp tất cả các so sánh giống như con trỏ, so với loại lớp và chỉ cần ít hơn so với được sử dụng trong một thùng chứa kết hợp, vì vậy chỉ cung cấp yêu cầu đó

Nhưng tôi không thấy lý do tại sao lựa chọn thay đổi tùy thuộc vào loại con trỏ thông minh. Tôi đang thiếu gì?


Bonus/liên quan: std::shared_ptr dường như đã đi theo từ boost::shared_ptr, và sau này bỏ qua các nhà khai thác quan hệ khác "bởi thiết kế" (và do đó std::shared_ptr làm quá). Tại sao điều này?

Trả lời

12

Đây là lỗi trong bản nháp của C++ 11; một báo cáo lỗi đã được mở để thay đổi tình trạng quá tải của các toán tử quan hệ std::unique_ptr để sử dụng std::less: xem LWG Defect 1297.

Điều này đã được khắc phục kịp thời cho đặc tả C++ 11 cuối cùng. C++ 11 §20.7.1.4 [unique.ptr.special]/5 xác định rằng operator< quá tải:

Returns:less<CT>()(x.get(), y.get())

nơi xy là hai toán hạng của toán tử và CT là loại phổ biến của hai con trỏ (vì con trỏ đến các loại khác nhau, ví dụ với các trình độ cv khác nhau, có thể được so sánh).

+0

Ah, tôi nên xem xét ở đó trước. :) Điều đó chắc chắn trả lời sự thay đổi trong phương pháp, nhưng bạn có biết tại sao 'shared_ptr' sẽ không cung cấp tất cả các toán tử quan hệ khác? – GManNickG

+0

@GMan: Tôi nghĩ rằng đó có thể là một sai lầm. Chúng được liệt kê trong 20.9 trong bản tóm tắt ' ', nhưng chúng không thực sự có mặt trong 20.9.11.2.7 ... –

+0

@ James: Ồ, gọi tốt. Tôi đã chỉ được scoped trên phần 'shared_ptr'. Vâng, điều đó giải quyết mà tôi đoán. (Họ nên thực sự làm sạch mà lên.) Cảm ơn. – GManNickG