Currently I am wondering how to correctly use an std::unique_ptr as a member variable regarding const correctness.
The following example allows to change the content owned by my_foo despite is being const:
#include <iostream>
#include <memory>
struct foo {
foo() : value_ptr_(std::make_unique<int>(3)) {}
void increment() const {
++(*value_ptr_);
}
int get_value() const {
return *value_ptr_;
}
std::unique_ptr<int> value_ptr_;
};
int main() {
const foo my_foo;
std::cout << my_foo.get_value() << std::endl;
my_foo.increment(); // But my_foo is const!
std::cout << my_foo.get_value() << std::endl;
}
Replacing std::make_unique<T> with std::make_unique<const T> seems like a good solution at first glance. However this disallows to change the content of my_foo even if it is non-const:
#include <iostream>
#include <memory>
struct foo {
foo() : value_ptr_(std::make_unique<int>(3)) {}
void increment() {
++(*value_ptr_);
}
int get_value() const {
return *value_ptr_;
}
std::unique_ptr<const int> value_ptr_;
};
int main() {
foo my_foo;
std::cout << my_foo.get_value() << std::endl;
my_foo.increment(); // compiler error
std::cout << my_foo.get_value() << std::endl;
}
Having a pointer to an int like in this minimal example is of course not very meaningful, but in real code the unique_ptr could hold a pointer to a base class of something polymorphic, i.e. an object we would not be able to simply store by value.
So how can this situation be handled better?