Why can 'operator*' member function of std::unique_ptr be marked const ( https://en.cppreference.com/w/cpp/memory/unique_ptr/operator *) while functions like 'front()', 'back()', 'operator[]' etc in std::vector not be marked const? Both are returning non-const references to the resources they are managing.
The core problem is I can't understand the 1st part ie why we're able to mark 'operator*' as const ie how can the return type be 'T&' when the '*this' pointer in that function would be a const pointer (due to the function being marked const)?
The difference lies in the definition of a container .
A std::vector
is considered a container . This means that the objects managed by a std::vector
are considered parts of the vector .
The references returned from front()
, back()
and operator[]
must be const
if the vector is const
. Modifying those objects will modify the vector.
A std::unique_ptr
, however, is not a container . The object it manages is not considered to be part of the std::unique_ptr
. This means that modifying the managed object is not considered modifying the pointer.
Therefore, using operator*
on a pointer type will never change the pointer itself, and therefore the operation can always be considered const
.
std::optional
may provide some helpful context to this difference.
Despite having a syntax that resembles a pointer, it is effectively a container (with max_size of 1). Because it contains its managed object, its operator*
must obey the same const
rules that a container does.
Drew Dormann's excellent answer above resolves the core confusion that I had. Adding a summary here (since it is too long to be posted as a comment) for complete clarity.
Doubt 1 : How are we able to use T&
as the return type even though std::unique_ptr::operator*()
is marked a const function?
Answer 1 : std::unique_ptr
just stores the pointer to the data being managed (the data itself is not stored within the class, but rather on the heap). We're able to mark its operator*()
function as const because we're returning a non-const reference to the actual data being stored & since that data itself is not stored inside the class, the 'const' qualifier just makes the pointer to the data const (ie we have a const pointer) but the data that this const pointer points to is still non-const and we can bind non-const references to it.
Doubt 2 : The same thing is true for std::vector
(ie the data managed by it is not stored within the class, but on the heap instead) but then why we don't similarly mark functions like std::vector::front()
, std::vector::back()
etc as const?
Answer 2 : This is due to the semantics associated with container classes in C++. Quoting Drew from above - std::vector models properties of an array, while a std::unique_ptr models properties of a pointer . So we kind of act as if the data managed by std::vector
resides inside the class. Note that std::optional
is different from std::unique_ptr
/ std::vector
as the data being managed is actually stored within the class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.