2014-04-07 23 views
7

Lần đầu tiên tôi đã cố gắng để viết một loạt trụ sở vòng lặp for để lặp qua unique_ptrs tôi đã viết:Làm thế nào để viết một unique_ptr có con trỏ và dữ liệu là const

std::vector<std::unique_ptr<Foo>> vec; 
// Initialize vec 

for (auto v : vec) // error 
{} 

sau đó tôi nhận ra điều này đang cố gắng để tạo ra một bản sao của mỗi phần tử không có ý nghĩa với unique_ptr. Vì vậy, sau đó tôi đã viết nó như là một tài liệu tham khảo:

for (auto& v : vec) 
{} 

Thêm một const ở phía trước nó giúp tôi thay đổi con trỏ.

for (const auto& v : vec) 
{ 
    v = nullptr; // error (good!) 
} 

Tôi làm cách nào để viết dữ liệu được trỏ đến không thể thay đổi? Ví dụ, mã sau không nên biên dịch.

for (??? v : vec) 
{ 
    v->func(); 
} 

class Foo 
{ 
public: 
    void func(); 

private: 
    bool mBar; 
} 

Foo::func() 
{ 
    mbar = true; // Should cause error 
} 
+0

Bạn có luôn luôn cần pointee là 'const' (và do đó có thể thay đổi định nghĩa' vec') hay bạn chỉ cần nó là 'const' * cho vòng lặp * này? –

+0

Một ứng dụng khác có thể là viết chức năng thanh tra, vì vậy tốt nhất là chỉ cho vòng lặp. Tuy nhiên, từ những câu trả lời thì điều này nghe không có vẻ. – user870130

+0

xem tại đây: http://stackoverflow.com/questions/15518894/forcing-use-of-cbegin-cend-in-range-based-for – user1095108

Trả lời

5

Để ngăn chặn các dữ liệu không bị thay đổi, bao gồm const trong các mẫu tham số cho con trỏ của bạn:

std::vector<std::unique_ptr<const Foo>> vec; 

Tôi nghĩ rằng bạn sẽ có vấn đề làm cho con trỏ tự const mặc dù. Lý do là vector phải có khả năng sao chép đối tượng con trỏ xung quanh nội bộ (ví dụ: khi vùng chứa được thay đổi kích cỡ). Với một unique_ptr, điều đó có nghĩa là quyền sở hữu phải được chuyển giữa các cá thể, có nghĩa là nó phải được thay đổi (không phải const).

Để tự tạo con trỏ const, tôi nghĩ bạn có hai lựa chọn chính: sử dụng vectơ const shared_ptr<> hoặc một mảng (nghĩa là kích thước cố định) là const unique_ptr<>.

3

Cho rằng, unique_pointer của bạn phải được khởi tạo cho một loại -qualified const, như thế này:

std::vector<std::unique_ptr<const Foo>> vec; 

Nhưng có lẽ nó là đủ để sử dụng iterator để khởi một tài liệu tham khảo liên tục vào đầu vòng lặp, trình biên dịch phải tối ưu hóa nó đi:

for (const auto& v_iter : vec) { 
    const auto& x = *v_iter; 
    do_things(...); 
} 

Mọi thứ khác là hackery.

Điều gì có thể hoạt động là giải thích vector<unique_pointer<Foo>> của bạn là vector<unique_pointer<const Foo>>, nhưng có thể dẫn đến hành vi không xác định vui nhộn nếu vector hoặc unique_pointer có chuyên môn. Đừng cố gắng, nó không phải là giá trị đó.

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