Tôi có thể cung cấp, như một deleter, bất kỳ loại chức năng nào (hoặc các đối tượng có thể gọi), miễn là tham số đầu tiên là int*
.
Không, không thực sự. Các nhà xây dựng std::shared_ptr
có hợp đồng sau đây, được tìm thấy trong phần 20.8.2.2.1 ([util.smartptr.shared.const]
):
template<class Y, class D> shared_ptr(Y* p, D d);
template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template <class D> shared_ptr(nullptr_t p, D d);
template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
Yêu cầu: p
sẽ chuyển đổi thành T*
. D
sẽ là CopyConstructible. Trình tạo bản sao và hàm hủy của D
sẽ không ném ngoại lệ. Biểu thức d(p)
phải được tạo thành tốt, phải có hành vi được xác định rõ và không được ném ngoại lệ. A sẽ là người cấp phát (17.6.3.5). Các nhà xây dựng bản sao và destructor của A sẽ không ném ngoại lệ.
Hiệu ứng: Xây dựng đối tượng shared_ptr
sở hữu đối tượng p
và deleter d
. Các nhà thầu thứ hai và thứ tư sẽ sử dụng một bản sao của a
để cấp phát bộ nhớ để sử dụng nội bộ.
Điều kiện sau: use_count() == 1 && get() == p
.
Ném: bad_alloc
hoặc ngoại lệ được triển khai khi tài nguyên không phải là bộ nhớ không thể nhận được.
An toàn ngoại lệ: Nếu ngoại lệ bị ném, hãy gọi d(p)
.
Yêu cầu này mạnh hơn rất nhiều so với tham số đầu tiên của dấu phân cách phải là loại phù hợp.Nó phải là tham số duy nhất (không có đối số mặc định), chẳng hạn như d(p)
là hợp pháp. Điều này hơi linh hoạt hơn std::function<void (int*)>
, bởi vì kiểu trả về có thể là bất kỳ thứ gì, nhưng nó cũng bị ràng buộc nhiều hơn đối với các bảo đảm ngoại lệ.
Nếu trình biên dịch của bạn không bắt được bạn khi bạn cung cấp một deleter với nhiều tham số bắt buộc, việc triển khai thư viện chuẩn đang làm điều gì đó không đúng.
Theo như cách triển khai, hãy tận dụng thực tế là nó phải là CopyConstructible. Ví dụ, lambda sau nên làm việc khá độc đáo, và có thể chuyển nhượng để std::function<void(void)>
(bảo lãnh CopyConstructible đảm bảo rằng chụp bởi công trình giá trị):
[d, p] { d(p); }
Bạn có muốn biết về trình biên dịch và thư viện cụ thể của bạn? (Nếu có, hãy cho chúng tôi biết bạn đang sử dụng cái gì) Hoặc C++ Standard nói gì về tất cả các triển khai phù hợp? –
Tôi sẽ biết làm thế nào tôi có thể làm một cái gì đó như thế. Tôi sẽ chỉnh sửa tin nhắn. – Toccio
@Toccio: Hành vi đó được bật bởi các mẫu. Đó là một chủ đề nâng cao. Kudos cho câu hỏi, đó là hợp lý và cũng đặt. – Jon