2015-06-01 16 views
9

Ví dụ này biên dịch và chạy tốt với gcc 4.8.3:constructor unique_ptr với deleter tùy chỉnh sẽ bị xóa

#include <memory> 
#include <functional> 
#include <iostream> 

int main() { 
    auto str = new const char[6]{'h', 'e', 'l', 'l', 'o', '\0'}; 
    std::unique_ptr<const char[], std::function<void(const char *)>> u_ptr(str, [](const char *s){ delete[] s; }); 
    std::cout << u_ptr.get() << std::endl; 
} 

Nhưng khi tôi thử nó với Visual Studio Professional 2013 nó không biên dịch (than phiền về một chức năng xóa). Đây có phải là chưa thể với Visual Studio 2013? Hay mã mẫu của tôi sai và gcc bỏ qua lỗi của tôi?

Lỗi là:

main.cpp (8): lỗi C2280: 'std :: unique_ptr> :: unique_ptr> (_ Ptr2, _Dx2): cố gắng tham khảo một chức năng xóa với [ _Ptr2 = const char *, _Dx2 = chính :: ] C: \ Program Files (x86) \ Microsoft Visual Studio 12.0 \ VC \ INCLUDE \ memory (16 16): xem khai báo 'std :: unique_ptr>: : unique_ptr '

+0

Làm việc với tiếng kêu. –

+3

Nên có câu hỏi thường gặp về "tại sao lại sử dụng' std :: function' như một dấu phân cách 'unique_ptr' một ý tưởng khủng khiếp?" –

+0

[OT]: khi bạn không nắm bắt bất cứ điều gì, bạn có thể bỏ qua không cần thiết '=' trong '[=]'. – Jarod42

Trả lời

6

Điều này dường như là một lỗi trong thư viện chuẩn Visual C++ 2013. Tôi không thể tạo lại vấn đề trên 2015.

Lớp unique_ptr có constructor này đã dành một con trỏ và một deleter:

unique_ptr(pointer _Ptr, 
    typename _If<is_reference<_Dx>::value, _Dx, 
     const typename remove_reference<_Dx>::type&>::type _Dt) _NOEXCEPT 
    : _Mybase(_Ptr, _Dt) 
    { // construct with pointer and (maybe const) deleter& 
    } 

Tuy nhiên, unique_ptr<T[]> chuyên môn cũng có một nhận tất cả constructor:

template<class _Ptr2, 
    class _Dx2> 
    unique_ptr(_Ptr2, _Dx2) = delete; 

Phiên bản này được ưu tiên hơn phiên bản trước.

Tuy nhiên, vì không chuyên ngành unique_ptr hoàn toàn không có, thay đổi u_ptr thành const char thay vì const char[] khắc phục sự cố.

Sử dụng phiên bản mảng với một deleter như bạn đang làm cũng là không cần thiết:

  1. Nếu bạn muốn gọi delete[] trên con trỏ của bạn, có đã là một chuyên môn hóa cho mảng. Bạn không cần một deleter tùy chỉnh.

  2. Nếu bạn muốn làm điều gì đó khác, bạn nên sử dụng phiên bản không chuyên biệt.

+0

as Tôi đã đề cập trong bình luận của tôi về câu hỏi 'std :: unique_ptr ' đã được cung cấp. Không cần thiết cho một deleter tùy chỉnh ở đây. – Mgetz

+1

@Mgetz OP hỏi xem mã của anh ấy có đúng cú pháp không (Và tại sao trình biên dịch không đồng ý). Sự tồn tại của một deleter đã thích hợp là không liên quan, khi anh ta cung cấp một [MCVE] (http://stackoverflow.com/help/mcve) và anh ta có thể cần, trong vấn đề thực tế thực sự, để sử dụng một deleter tùy chỉnh. –

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