微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

列表迭代器参考 - 程序输出

如何解决列表迭代器参考 - 程序输出

给定以下算法:

#include <iostream>
#include <list>

int main ()
{
  std::list<int> mylist = {5,10,15,20};

  std::cout << "mylist contains:"<<"\n";

  //for (auto it = mylist.begin(); it != mylist.end(); ++it)
  auto it = mylist.begin();
  while ( it != mylist.end())
  {
      std::cout << *it;
      std::cout << "    "<< &it<<std::endl;
      it++;
  }

  std::cout << '\n';

  return 0;
}

这个程序的输出是:

mylist contains:
 5     0x7dc9445e5b50
 10    0x7dc9445e5b50
 15    0x7dc9445e5b50
 20    0x7dc9445e5b50

既然我们移动了迭代器,为什么地址没有改变?

我排除了引用的 4 字节偏移量。

解决方法

试试这个:

  std::cout << "    "<< &*it<<std::endl;

阅读本文以了解传统双向迭代器的描述。

https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator

从本文档中可以看出这一点并不是很明显,但是对于这个迭代器和整个 STL 中的迭代器,运算符 *() 将返回:

  T & operator *();

  const T & operator *() const; // for const iterators (list iterator in this case).

我希望这比我之前的简洁回答更具说明性。

,

您的问题很简单:it 是一个变量。现在,您正在打印该变量的地址。您为该变量分配了不同的,但该变量在其存在的整个过程中都存储在内存中的同一位置,因此当您打印出其地址时,您每次都会看到相同的值。

您想要做的是打印出存储在该变量中的值——迭代器引用的对象的地址。就迭代器而言,这样做可能有些棘手,因为迭代器是一种抽象——根据设计,您并不真正知道它包含什么。

然而,我们可以相当可靠地猜测关于 std::list 的迭代器可能是如何实现的。特别是,它可能是这样的:

template <class T>
class iterator {
    T *data;
public:
    T &operator*() { return *data; }

    // ... and many more functions we don't care about for now
};

这里的重点是,尽管 it 可能会存储不同的数据以产生其结果,但 operator* 需要返回对迭代器所引用对象的引用。因此,为了获取(至少有效地)存储在迭代器中的地址,我们可以使用 operator* 获取对对象的引用,然后使用 & 获取地址那个对象。

缺点:虽然这会告诉您迭代器在不同时间引用的对象的地址,但它不一定会告诉您迭代器本身真正包含什么。只要迭代器从指定的操作中产生正确的结果,迭代器基本上可以以任何它认为合适的方式自由地产生它们(但也就是说,对于 std::list 的迭代器,是的,它可能会使用指针)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。