2012-10-03 45 views
10

Tôi đã cố gắng giới thiệu một số độ chính xác const (thực tế là mô hình chức năng) cho một số mã mới và thấy rằng tôi không thể chuyển một số std::shared_ptr<A> đến một hàm mong đợi một std::shared_ptr<A const>. Lưu ý rằng tôi không muốn bỏ cách xa constness nhưng giới thiệu nó, hợp pháp với các con trỏ thô.Tại sao không shared_ptr <A> chuyển đổi ẩn thành shared_ptr <A const>?

Có cách nào để giải quyết vấn đề này không? Tôi đã không tìm thấy một thành viên chức năng để làm điều này.


Các lỗi chính xác thốt ra bởi g ++ 4.6.1 là:

error: no matching function for call to ‘foo(std::shared_ptr<A>)’ 
note: candidate is: 
note: template<class T> std::shared_ptr<_Tp> foo(std::shared_ptr<const _Tp>) 

Trả lời

9

Các vấn đề trong trường hợp của bạn không phải là với các chuyển đổi có thể từ/đến khác nhau std::shared_ptr, nhưng là có liên quan đến cách suy luận kiểu hoạt động cho các hàm mẫu.

Khi trình biên dịch cố khớp một cuộc gọi hàm với mẫu, nó sẽ chỉ chấp nhận kết hợp chính xác, tức là không có chuyển đổi loại nào. Trong trường hợp này, hàm của bạn mất std::shared_ptr<const T> và người gọi có một số std::shared_ptr<U> trong đó U không phải là const. Vì khớp không phải là chính xác, nó sẽ hủy mẫu và chọn ứng cử viên quá tải tiếp theo.

Các cách giải quyết đơn giản là: tránh suy luận kiểu hoàn toàn và cung cấp các mẫu tranh luận:

std::shared_ptr<A> p; 
foo<A>(p);    // will use the templated shared_ptr conversion 

Hoặc thực hiện việc chuyển đổi bản thân:

foo(std::shared_ptr<const A>(p)); 
+0

'std :: static_pointer_cast (p) 'là một cách để thực hiện chuyển đổi một cách rõ ràng. –

+0

@Luc: Tại sao không 'std :: const_pointer_cast (p)'? – Xeo

+1

@Xeo Vì chúng tôi không loại bỏ cv-vòng loại. –

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