为什么我需要将迭代器解除引用到智能指针两次而不是使用operator->()?

时间:2014-10-01 15:23:58

标签: c++11 iterator containers smart-pointers

假设我有以下代码:

#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 worksthat we need to dereference twice instead of an arrow

4 个答案:

答案 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;