Why would I need to play out the iterator with a smart pointer twice instead of using the -> () operator?
Suppose I have the following code:
#include <iostream>
#include <deque>
#include <memory>
struct Test
{
int test;
};
int main(int, char**)
{
std::deque<std::unique_ptr<Test>> deque;
deque.push_back(std::unique_ptr<Test>(new Test{10}));
auto start = deque.begin();
std::cout << start->test << std::endl; // <- compilation error
std::cout << (start.operator->())->operator->()->test << std::endl; // <- OK
}
Why is smart-pointer treated as if it were a normal pointer object, although it is not (as I understand it)? From what I know, operator->()
must repeat until it reaches T*
.
Here are some related questions about how arrow overloading works and what we need to dereference twice instead of an arrow .
source to share
For an iterator, the it
expression is it->m
equivalent (*i).m
, technically it means that the iterator operator->
returns a raw pointer to the contained object. In your case, that means it returns a raw pointer to unique_ptr
. For this, the final one is applied operator->
and you get a reference to the contained object. This is why the chaining doesn't happen operator->
.
source to share
The arrow operator is overloaded for unique_ptr . Since you have an iterator, you are casting unique_ptr
, not the object that belongs to it. Therefore, you need to cast it twice.
std::cout << (*start)->test << std::endl;