2012-02-28 15 views
6

Tôi không hiểu tại sao các công trình sau đây (mặc dù tôi vui mừng rằng nó hoạt động!):Tại sao tính năng này hoạt động? std :: set tìm thấy với phím tìm kiếm và tùy chỉnh so sánh

tôi có thể xác định một std::set của đối tượng với một so sánh tùy chỉnh. So sánh tùy chỉnh này hoạt động bằng cách so sánh một số biến thành viên của hai đối tượng được so sánh. NHƯNG thì tôi có thể sử dụng chức năng .find(x) của .find(x) với x là loại biến thành viên chứ không phải chính đối tượng và nó hoạt động!

Dưới đây là một ví dụ cực kỳ đơn giản:

my_class.h

class my_class //just hold an integer 
{ 
    public: 
     int an_int; 

    my_class(int new_int) : an_int(new_int) 
    { } 


    //compare instances of this class by comparing their integers... 
    struct compare_instances 
    {  
     bool operator() (const my_class &a, const my_class &b) const 
     { 
     return a.an_int < b.an_int; 
     } 
    }; 
}; 

main.cpp:

... 
std::set<my_class, my_class::compare_instances> my_class_set; 
my_class_set.insert(my_class(18)); 
my_class_set.insert(my_class(7) ); 
my_class_set.insert(my_class(22)); 

std::set<my_class, my_class::compare_instances>::const_iterator found_it 
        = my_class_set.find(18); 
std::fprintf(stderr, "found_it->an_int = %d\n", found_it->an_int); 

Output: "found_it-> an_int = 18" !!!! !!

Tôi đã mong đợi mã trên không biên dịch và trình biên dịch sẽ hét lên với tôi rằng "18 không thuộc loại my_class". Nhưng nó không ...

Không nên đối số với .find có cùng loại với các thành phần của chính số set? Đó là những gì tài liệu dường như nói ...

+0

xem hàm tạo của bạn: 'my_class (int new_int)'. bạn có thể tạo 'my_class' bắt đầu từ' int'. thử và 'tìm (" blah ")' và nó sẽ không biên dịch :) – vulkanino

Trả lời

12

Điều này hoạt động vì int hoàn toàn có thể chuyển đổi thành lớp học của bạn. Bất kỳ hàm tạo nào không được đánh dấu explicit và có thể được gọi với chính xác một đối số không thuộc loại của chính lớp đó định nghĩa một chuyển đổi ngầm định. Điều này có nghĩa là, bất cứ khi nào một đối tượng thuộc loại lớp được mong đợi, bạn cũng có thể sử dụng int và nó sẽ tự động được chuyển đổi.

+0

Ok, bạn đã thêm tất cả các điểm vào câu trả lời của bạn. Tôi đang xóa các nhận xét khác của mình. 8v) –

+0

@FredLarson ngay cả khi có thể không liên quan, bạn có muốn giới thiệu ** luôn luôn ** khai báo các nhà xây dựng rõ ràng không? – vulkanino

+0

@vulkanino: Nếu bạn không muốn chuyển đổi ngầm, nó có thể không phải là một ý tưởng tồi. Tôi không biết về bất kỳ vấn đề nào với việc thêm 'tường minh' vào một hàm tạo ngay cả khi nó không thể được sử dụng cho chuyển đổi ngầm định. –

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