2015-06-24 19 views
20

Tôi có một chức năng mà tạo ra một unique_ptr với một deleter tùy chỉnh và trả về nó:Di chuyển unique_ptr với deleter tùy chỉnh cho một shared_ptr

auto give_unique_ptr() { 
    auto deleter = [](int* pi) { 
     delete pi; 
    }; 
    int* i = new int{1234}; 
    return std::unique_ptr<int, decltype(deleter)>(i, deleter); 
} 

Trong mã khách hàng của chức năng đó, tôi muốn di chuyển unique_ptr vào một shared_ptr, nhưng tôi không biết làm thế nào để làm điều đó cho rằng tôi không biết decltype của deleter tùy chỉnh của tôi bên ngoài của chức năng.

Tôi đoán nó sẽ giống như thế này:

auto uniquePtr = give_unique_ptr(); 
auto sharedPtr = std::shared_ptr<..??..>(std::move(uniquePtr)); 

gì làm tôi phải viết thay vì .. ?? .. để có được đúng loại?

Nếu điều này là có thể, sẽ shared_ptr hoạt động tốt và gọi trình chỉnh sửa tùy chỉnh của tôi được tạo bên trong hàm give_unique_ptr() khi số lượng sử dụng của nó đạt đến 0?

+0

Hãy nhớ rằng 'shared_ptr' * erases * deleter. Thông số mẫu duy nhất là loại được trỏ đến trong chế độ xem hiện tại. – o11c

+0

@ o11c điều đó có nghĩa là gì? Tôi đã thử giải pháp được đề xuất bởi @Nawaz và deleter được gọi sau khi 'shared_ptr' bị hủy. – j00hi

+0

nó có nghĩa là loại của deleter không liên quan đến kiểu 'shared_ptr'. Bạn thậm chí có thể truyền tới, ví dụ: 'shared_ptr 'và nó vẫn sẽ gọi là deleter gốc. – o11c

Trả lời

19

Nếu bạn biết (hoặc muốn một cách rõ ràng gõ) các loại của đối tượng, sau đó bạn có thể làm điều này:

std::shared_ptr<int> sharedPtr(std::move(uniquePtr)); 

Các constructor của std::shared_ptr sẽ chăm sóc của deletor.


Nếu bạn, tuy nhiên, muốn loại thể suy đoán, sau đó:

auto sharedPtr = make_shared_from(std::move(uniquePtr)); 

nơi make_shared_from là:

template<typename T, typename D> 
std::shared_ptr<T> make_shared_from(std::unique_ptr<T,D> && p) 
{ 
    //D is deduced but it is of no use here! 
    //We need only `T` here, the rest will be taken 
    //care by the constructor of shared_ptr 
    return std::shared_ptr<T>(std::move(p)); 
}; 

Hy vọng rằng sẽ giúp.

+2

IMO, có lẽ sẽ tốt hơn nếu 'make_shared_from' lấy tham chiếu rvalue để làm cho nó có thể nhìn thấy rõ ràng rằng nó đang được chuyển từ –

+3

@RyanHaining hoặc thậm chí là một giá trị, đó là C++ 11 thành ngữ trong hầu hết các trường hợp. – o11c

+0

@RyanHaining: Điều đó cũng tốt. Làm thế nào về 'move_from' thay vì' make_shared_from'? – Nawaz

14
auto uniquePtr = give_unique_ptr(); 
auto sharedPtr = std::shared_ptr<decltype(uniquePtr)::element_type>(std::move(uniquePtr)); 

Và có, shared_ptr sẽ lưu trữ - và sau đó sử dụng - công cụ tùy chỉnh.

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