C++ 为什么迭代器不作为左值去引用

C++ 为什么迭代器不作为左值去引用,c++,stl,circular-buffer,C++,Stl,Circular Buffer,如果我的问题不包含所有相关信息,请道歉。请发表意见,我将作出相应的修改 我在Win7上与MinGW和gcc一起使用CLion 我一直在试验循环缓冲区,遇到了boost::circular\u buffer,但就我的项目规模而言,我想让Pete Goodlife使用它,它似乎只需一个.hpp就可以实现 注意:我知道如何减少增压依赖性,这要归功于 但是,以下Pete实现的示例的行为与预期不符,即std::nexture_difference(cbuf.begin(),cbuf.end(),df.b

如果我的问题不包含所有相关信息,请道歉。请发表意见,我将作出相应的修改

我在Win7上与MinGW和gcc一起使用CLion


我一直在试验循环缓冲区,遇到了
boost::circular\u buffer
,但就我的项目规模而言,我想让Pete Goodlife使用它,它似乎只需一个
.hpp
就可以实现

注意:我知道如何减少增压依赖性,这要归功于

但是,以下Pete实现的示例的行为与预期不符,即
std::nexture_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);
}
遗憾的是,对于C++来说,我不知道为什么<代码> df.No.[/]代码>迭代器不是作为Lo值被撤销的。p> 我认为罪魁祸首是(或不完全理解)Pete's
circular.h
中第72行的
循环缓冲区迭代器的成员调用:

elem_类型和运算符*(){return(*buf_)[pos_];}


非常感谢您的帮助。

std::nexture_difference
写入结果迭代器。在您的例子中,该结果迭代器指向
df
,其大小为0,容量为5。这些写入操作将被写入
df
的保留内存中,但不会更改容器的大小,因此大小仍然为0,保留容器空间的前3个整数将有您的差异。为了查看结果,要写入的容器必须已经在要写入的插槽中存储了数据


因此,要查看结果,必须在差异之前将数据放入循环缓冲区,然后将容器大小调整为适当的大小(基于
相邻_difference
返回的迭代器中,作为输出迭代器传递的迭代器被取消引用并作为左值处理,并且最有可能的是您期望的数据实际存储在循环缓冲区的缓冲区中

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

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

考虑以下代码:

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

这听起来像是双重工作,填充
df
,然后覆盖它们。我不知道这是否是
boost::circular\u buffer
所做的,但我没有这个问题。问题是,Pete的容器声称它是STL兼容的,我希望它在
相邻的
在向量上。我需要引入什么调整来触发状态更新?我想在阅读了中的
back\u inserter()
之后,我开始理解了,它基本上描述了我的用例。但是,我不确定为什么CPPPreference会包含这样一个示例。。。
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
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::adjacent_difference(
    cbuf.begin(), cbuf.end(),
    std::back_inserter(df));