The first time I tried to write a range based for loop to iterate over unique_ptrs I wrote:
std::vector<std::unique_ptr<Foo>> vec;
// Initialize vec
for (auto v : vec) // error
{}
I then realized this is trying to create a copy of each element which doesn't make sense with a unique_ptr. So then I wrote it as a reference:
for (auto& v : vec)
{}
Adding a const in front of it keeps me from changing the pointer.
for (const auto& v : vec)
{
v = nullptr; // error (good!)
}
How can I write it, so that the data pointed to cannot be changed? For example, the following code should not compile.
for (??? v : vec)
{
v->func();
}
class Foo
{
public:
void func();
private:
bool mBar;
}
Foo::func()
{
mbar = true; // Should cause error
}
To prevent the data from being modified, include const
in the template parameter for your pointer:
std::vector<std::unique_ptr<const Foo>> vec;
I think you'll have problems making the pointer itself const
though. The reason is that the vector has to be able to copy the pointer object around internally (e.g. when the container is resized). With a unique_ptr
, that means ownership has to be transferred between instances, meaning it has to be mutable (not const).
To make the pointer itself const
, I think you've got two main choices: use a vector of const shared_ptr<>
, or an array (i.e. fixed size) of const unique_ptr<>
.
For that, your unique_pointer
must be instantiated for a const
-qualified type, like this:
std::vector<std::unique_ptr<const Foo>> vec;
But maybe it is enough to use the iterator to initialise a constant reference at the start of the loop, the compiler should optimise it away:
for (const auto& v_iter : vec) {
const auto& x = *v_iter;
do_things(...);
}
Everything else is hackery.
What probably would work is reinterpreting your vector<unique_pointer<Foo>>
as a vector<unique_pointer<const Foo>>
, but it might result in hilarious undefined behavior if either vector
or unique_pointer
has a specialisation. Do not try, it is not worth that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With