C++11 为什么我需要将迭代器解引用到智能指针两次,而不是使用运算符->;()?

C++11 为什么我需要将迭代器解引用到智能指针两次,而不是使用运算符->;()?,c++11,iterator,containers,smart-pointers,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 T

假设我有以下代码:

#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
}
#包括
#包括
#包括
结构测试
{
智力测验;
};
int main(int,char**)
{
std::德克-德克;
deque.push_back(std::unique_ptr(新测试{10}));
自动启动=deque.begin();
std::cout test()->test箭头操作符是。因为您有一个迭代器,所以您将取消对
唯一\u ptr
的引用,而不是它所拥有的对象。因此,您需要取消引用两次

std::cout << (*start)->test << std::endl;   

std::cout test对于迭代器
it
,表达式
it->m
相当于
(*i).m
,从技术上讲,这意味着迭代器的
运算符->
返回一个指向所包含对象的原始指针。在您的情况下,这意味着它返回一个指向
唯一的\u ptr
的原始指针。最后一个
运算符->
将应用于该对象,您将得到对所包含对象的引用。这就是为什么没有进一步的原因出现
运算符->
的链接。

std::unique\u ptr
这样的智能指针被实现来存储指针,其行为类似于C指针,而迭代器本身也是指针


那么为什么需要取消引用两次呢?因为您有一个指向指向
Test

的指针,这与您有一个普通指针容器完全相同:

std::deque<Test*> dq;
dq.push_back(new Test{10});
auto start = dq.begin();
std::cout << (*start)->test << std::endl;
std::deque dq;
dq.推回(新测试{10});
自动启动=dq.begin();

std::cout test这里提到的重新应用程序只指当
运算符->
返回非指针时。迭代器的
运算符->
返回一个指向该值的指针,然后该值需要再次取消引用。如果它返回一个指向该值的引用,它将链接。顺便说一句,我更喜欢
(*start)->测试
。如果
操作符->
将通过引用返回
唯一的\u ptr
操作符->
将落入指向的对象,因为这是它的工作方式(递归直到遇到指针)。因此它实际上并不能解释任何事情。这是“等价的”不幸的是,迭代器的情况对我来说仍然有点奇怪。但这个解释似乎很适合,谢谢。