Why does std::unique_ptr not have a const get method?
For the same reason a T*const
when dereferenced is a T&
, not a T const&
.
Constness of pointer is distinct from pointness of pointed-to.
get
is const, it does not modify the state of unique_ptr
.
Its constness does not impact the constness of the contents.
There is the idea of smart pointers that propogate constness, but unique_ptr
is not that beast.
std::experimental::propogate_const
wraps a pointer-like object and makes const
travel through it.
It, or something like it, may solve your problem.
Note that I find half the time when I try to have const propogate like this, I discover I was wrong. But this may not be the case here.
In general, the proper way to handle the guts of a T*const
in a const
manner is to pass a T const&
(or the nullable variant T const*
).
Smart pointers are pretending to be a raw pointer.
If you have class member which is raw pointer and use it in const
method that you can't update a pointer, but you can modify object which is pointed.
Same behavior is desired for smart pointer. So std::unique_ptr::get
is a const
method, but doesn't force to return pointer to const
object.
Note also that you can have a pointer to const
object.
MyClass *pointerToObject
std::unique_ptr<MyClass> smartPointerToObject;
// but you can have also a case
const MyClass *pointerToConstObject
std::unique_ptr<const MyClass> smartPointerToConstObject;
In last case std::unique_ptr::get
will return something you are expecting.
Based on comment below:
Just provide private methods:
InnerClass& GetField() { return *uniquePtrToInnerClass; }
const InnerClass& GetField() const { return *uniquePtrToInnerClass; }
And use it in your code and you will have const object of inner class in const method.
There's no point to giving read-only access to an object via its unique_ptr
. You only pass unique_ptr
around when you are transferring ownership, for access to the object without an ownership transfer, call up.get()
and pass a const T*
to the function that should only read (or if the pointer is never nullptr
, it's also reasonable to evaluate *(up.get())
and pass a const T&
).
As a bonus, this allows you to use that function with objects stored on the stack, embedded inside another object, or managed with a smart pointer other than unique_ptr
.
There's a good discussion of all the unique_ptr parameter passing cases (in/out, const/non-const, etc) here:
- How do I pass a
unique_ptr
argument to a constructor or a function?