假设我有以下代码:
#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
}
为什么智能指针被视为常规指针对象,虽然它不是(据我所知)?据我所知,operator->()
应该重复,直到达到T*
。
以下是一些相关问题on how arrow overloading works和that we need to dereference twice instead of an arrow。
答案 0 :(得分:5)
对于迭代器it
,表达式it->m
等同于(*i).m
,从技术上讲,它意味着迭代器的operator->
返回原始指针到包含的对象。在你的情况下,它意味着它返回一个指向unique_ptr
的原始指针。最终operator->
将应用于此,您最终会得到对包含对象的引用。这就是operator->
没有进一步链接的原因。
答案 1 :(得分:0)
箭头操作符为overloaded for unique_ptr。因为您有一个迭代器,所以您取消引用unique_ptr
,而不是它拥有的对象。因此,您需要解除引用两次。
std::cout << (*start)->test << std::endl;
答案 2 :(得分:0)
像std::unique_ptr
这样的智能指针用于存储指针,其行为类似于C指针,而迭代器本身也是指针。
那你为什么需要两次解除引用?只是因为你有一个指向Test
的指针。
答案 3 :(得分:0)
它就像你有一个普通指针容器一样:
std::deque<Test*> dq;
dq.push_back(new Test{10});
auto start = dq.begin();
std::cout << (*start)->test << std::endl;