繁体   English   中英

为什么迭代器不会被解除引用为左值

[英]Why iterator is not dereferenced as an lvalue

如果我的问题不包含所有相关信息,请道歉。 请评论,我会相应修改。

我使用WinG上的CLion和MinGW和gcc


我一直在尝试使用循环缓冲区并且遇到了boost::circular_buffer ,但是对于我的项目的大小,我想使用Pete .hpp 循环缓冲区 ,这似乎只是一个.hpp的可靠实现。

注意 :由于Boost依赖项和bcp,我知道如何减少boost依赖性

但是,以下使用Pete实现的示例并不像预期的那样,即std::adjacent_difference(cbuf.begin(),cbuf.end(),df.begin()); 出来了。 我想了解为什么并可能纠正它的行为。

关注MWE:

#include "circular.h"
#include <iostream>
#include <algorithm>

typedef circular_buffer<int> cbuf_type;

void print_cbuf_contents(cbuf_type &cbuf){
  std::cout << "Printing cbuf size("
            <<cbuf.size()<<"/"<<cbuf.capacity()<<") contents...\n";
  for (size_t n = 0; n < cbuf.size(); ++n)
    std::cout << "  " << n << ": " << cbuf[n] << "\n";

  if (!cbuf.empty())  {
    std::cout << "  front()=" << cbuf.front()
              << ", back()=" << cbuf.back() << "\n";
  }  else  {
    std::cout << "  empty\n";
  }
}

int main()
{
  cbuf_type cbuf(5);
  for (int n = 0; n < 3; ++n) cbuf.push_back(n);
  print_cbuf_contents(cbuf);

  cbuf_type df(5);
  std::adjacent_difference(cbuf.begin(),cbuf.end(),df.begin());
  print_cbuf_contents(df);
}

其中打印以下内容:

Printing cbuf size(3/5) contents...
  0: 0
  1: 1
  2: 2
  front()=0, back()=2
Printing cbuf size(0/5) contents...
  empty

不幸的是,作为c ++的新手,我无法弄清楚为什么df.begin()迭代器不会被解除引用为左值。

我认为罪魁祸首是(或者不完全理解)Pete's circular.h第72行的circular_buffer_iterator的成员调用:

elem_type &operator*() { return (*buf_)[pos_]; }

很感谢任何形式的帮助。

作为输出迭代器传递的迭代器被解除引用并被视为左值,并且很可能您期望的数据实际存储在循环缓冲区的缓冲区中。

问题是,除了实际的存储缓冲区之外,大多数容器还包含一些必须维护的内部簿记状态。 (例如:缓冲区中有多少元素,剩余多少空间等)。

取消引用和递增容器不会更新内部状态,因此容器“不知道”已添加新数据。

请考虑以下代码:

std::vector<int> v;
v.reserve(3);

auto i = v.begin();
*(i++) = 1; // this simply writes to memory
*(i++) = 2; // but doesn't update the internal
*(i++) = 3; // state of the vector
assert(v.size() == 0); // so the vector still "thinks" it's empty

使用push_back将按预期工作:

std::vector<int> v;
v.reserve(3);

v.push_back(1); // adds to the storage AND updates internal state
v.push_back(2);
v.push_back(3);

assert(v.size() == 3); // so the vector "knows" it has 3 elements

在您的情况下,您应该使用std :: back_inserter,这是一个迭代器,每次取消引用时都会在容器上调用“push_back”:

std::adjacent_difference(
    cbuf.begin(), cbuf.end(),
    std::back_inserter(df));

std::adjacent_difference写入结果迭代器。 在你的情况下,结果迭代器指向df ,其大小为0,容量为5.这些写入将进入df的保留内存, 但不会改变容器的大小 ,因此大小仍为0 ,保留容器空间的前3个int将有你的区别。 为了查看结果,正在写入的容器必须已经存储在正在写入的插槽中的数据。

因此,要查看结果,必须在差异之前将数据放入循环缓冲区,然后将容器的大小调整为适当的大小(基于adjacent_difference返回的迭代器)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM