How to write unique_ptr whose pointer and data are const

The first time I tried to write a range based on a loop to iterate over unique_ptrs, I wrote:

std::vector<std::unique_ptr<Foo>> vec; // Initialize vec for (auto v : vec) // error {} 

Then I realized that this is an attempt to create a copy of each element, which does not make sense with unique_ptr. So, I wrote this as a link:

 for (auto& v : vec) {} 

Adding a constant in front of it prevents me from changing the pointer.

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

How can I write it so that the data it points to cannot be changed? For example, the following code should not be compiled.

 for (??? v : vec) { v->func(); } class Foo { public: void func(); private: bool mBar; } Foo::func() { mbar = true; // Should cause error } 
+7
c ++ unique-ptr
source share
2 answers

To prevent data from being modified, include const in the template parameter for your pointer:

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

I think you will have problems creating the const pointer itself. The reason is because the vector must be able to copy the pointer object inside (for example, when the size of the container changes). Using unique_ptr this means that ownership must be transferred between instances, i.e. it must be mutable (not const).

To make the const pointer itself, I think you have two main options: use the const shared_ptr<> vector or the array (i.e. fixed size) const unique_ptr<> .

+5
source share

For this, your unique_pointer must be created for a const -qualified type, for example:

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

But perhaps it’s enough to use an iterator to initialize the permalink at the beginning of the loop, the compiler should optimize it:

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

Everything else is hacking.

Which will probably work by reimagining your vector<unique_pointer<Foo>> as vector<unique_pointer<const Foo>> , but this can lead to fun undefined behavior if either vector or unique_pointer has specialization. Don’t try , it’s not worth it.

+3
source share

All Articles