tôi khám phá chủ đề này trong Coliru với lệnh đầu vào sau:Tại sao std :: shared_ptr <T> = std :: unique_ptr <T[]> biên dịch, trong khi std :: shared_ptr <T[]> = std :: unique_ptr <T[]> thì không?
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
thử nghiệm này có thể được tìm thấy here, nhưng tôi đã đăng tải đoạn code dưới đây. Tôi đã sử dụng int
trong ví dụ của mình vì đây là loại cơ bản.
#include <iostream>
#include <memory>
struct Foo{
Foo() :
a_{0}, b_{1}, c_{-1}, combination_{0.5} {}
int
a_,
b_,
c_;
double
combination_;
};
int main()
{
//int
// *unManagedArray = new int[16];
std::unique_ptr<int[]>
uniqueArrayOrigin = std::make_unique<int[]>(16);
std::shared_ptr<int>
// works but needs call to new
// sharedSingleTest{unManagedArray, std::default_delete<int[]>{}};
// works, does not require call to new
sharedSingleUnique = std::make_unique<int[]>(16);
// compilation error (conversion to non-scalar type)
// sharedSingleDerived = uniqueArrayOrigin;
// std::shared_ptr<int[]>
// compilation errors
// sharedArrayTest{unManagedArray, std::default_delete<int[]>{}};
// compilation error (conversion to non-scalar type)
// sharedArrayUnique = std::make_unique<int[]>(16);
// compilation error (conversion to non-scalar type)
// sharedArrayDerived = uniqueArrayOrigin;
std::shared_ptr<Foo>
// works: specified overload of operator= for shared_ptr
nonArrayTest = std::make_unique<Foo>();
std::cout << "done!\n";
}
Tôi đã nhìn quanh trên SO cho câu trả lời, nhưng chỉ bật lên references đến việc thực hiện std::shared_ptr
không có một chuyên môn hóa, và điều này chủ yếu là bởi vì không ai làm phiền để cho một thích hợp đề xuất với ủy ban tiêu chuẩn về đề tài này.
Tôi tò mò, bởi vì tôi sẽ giải thích tình trạng quá tải thứ 4 của operator=
, std::shared_ptr<T[]>.operator=(std::unique_ptr<T[], Deleter>&&)
trên cppreference để cho biết rằng cú pháp như thế là legal-- T[]
và T[]
là cùng loại không phụ thuộc vào trạng thái của các chuyên ngành với nhiều loại mảng cho std::shared_ptr
, sau khi tất cả . Ngoài ra, cú pháp này chỉ xuất hiện để hoạt động trên sản phẩm của std::make_unique<T[]>
và không phải là đối tượng con trỏ duy nhất, điều này đi ngược lại với sự hiểu biết của tôi về chủ đề - không nên thực hiện cuộc gọi một cách hiệu quả. và đối tượng kia, di chuyển một đối tượng vừa được tạo ra? Tôi sẽ mong đợi sự khác biệt duy nhất giữa chúng sẽ là không hợp lệ std::unique_ptr<T[]>
sau khi gọi hàm trong trường hợp đầu tiên. Là một lưu ý phụ, tôi giả định rằng vì có cách xây dựng một mảng được phân bổ động vào một shared_ptr
mà không yêu cầu sử dụng new
, tôi nên sử dụng nó với cuộc gọi lộn xộn và không an toàn hơn đến new T[N]
?
tl; dr:
operator=
không làm việc ở tất cả giữastd::shared_ptr<T[]>
vàstd::unique_ptr<T[]>
dù tôi mong chờ nó để làm việc. Tại sao?- Nếu có bất kỳ điều gì, tôi muốn chuyển đổi loại từ
T[]
thànhT
thành nguồn lỗi biên dịch giữa các con trỏ duy nhất và được chia sẻ. Tại sao điều này hoạt động? operator=
hoạt động giữastd::shared_ptr<T>
vàstd::make_unique<T[]>
nhưng không phảistd::unique_ptr<T[]>
. Tại sao?- Tôi có đúng để giả định trong trường hợp yêu cầu mảng được phân bổ động, được chia sẻ không, nhưng tôi không muốn sử dụng tăng hoặc véc tơ (lý do bên dưới), tôi nên gọi
operator= std::make_unique<T[]>(N)
?
Tại sao tôi không sử dụng?
- Boost: không được chấp thuận cho sử dụng được nêu ra trong công ty của tôi, và tôi không biết khi nào hoặc nếu tôi sẽ nhận được sự chấp thuận để sử dụng nó.
- Mảng: Tôi phải xác định kích thước của mảng này khi chạy.
- Vectơ: Tôi đang làm việc trên hệ thống xử lý tín hiệu thời gian thực và muốn tránh sự chú ý thêm con trỏ. Tôi cũng cố gắng tránh các thư viện không liên quan trong các tệp tiêu đề của tôi (đây là thông tin liên lạc giữa đọc và viết hệ thống con) Tuy nhiên, cuối cùng tôi đã chọn tối ưu hóa sau này, nếu nó quan trọng (tối ưu hóa sớm ...) và cắn đạn. Câu hỏi vẫn còn, mặc dù.
Hiện tại, 'std :: shared_ptr' không hỗ trợ mảng. –
Để làm rõ: Nó không chỉ đơn thuần là trường hợp một chuyên môn cho các loại mảng không tồn tại, nhưng 'std :: shared_ptr' chủ động không hỗ trợ mảng? Tôi đã giả định rằng việc thiếu chuyên môn có nghĩa là nó hoạt động trên các loại mảng như chúng là bất kỳ loại nào khác. – jaggedSpire