Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;不在内部使用std::vector或std::list的std::迭代器 我尝试(作为练习)在C++中创建一个简单的数值范围类。它将允许您迭代均匀间隔的双精度(如numpy/Pythonarange):_C++_Stl_Iterator - Fatal编程技术网

C++;不在内部使用std::vector或std::list的std::迭代器 我尝试(作为练习)在C++中创建一个简单的数值范围类。它将允许您迭代均匀间隔的双精度(如numpy/Pythonarange):

C++;不在内部使用std::vector或std::list的std::迭代器 我尝试(作为练习)在C++中创建一个简单的数值范围类。它将允许您迭代均匀间隔的双精度(如numpy/Pythonarange):,c++,stl,iterator,C++,Stl,Iterator,我想做什么(但使用迭代器): double lower = ..., upper = ..., delta = ...; for (double val = lower; val < upper; val += delta) { // do something with val f(val); } // include the last val to guarantee upper is included or exceeded f(val); // do something

我想做什么(但使用迭代器):

double lower = ..., upper = ..., delta = ...;
for (double val = lower; val < upper; val += delta)
{
   // do something with val
   f(val);
}
// include the last val to guarantee upper is included or exceeded
f(val); // do something with val
class NumericRange
{
protected:
  double lower, upper, delta;
  std::vector<double> sorted_range;
public:
  typedef std::vector<double>::const_iterator const_iterator;
  NumericRange()
  {
    lower = upper = delta = std::numeric_limits<double>::quiet_NaN();
    // vector is constructed empty
  }
  NumericRange(double lower_param, double upper_param, double delta_param)
  {
    lower = lower_param;

    upper = upper_param;
    delta = delta_param;
    assert(upper_param > lower_param);

    double val;
    // note: can be much faster without push_back
    for (val = lower_param; val < upper_param; val += delta_param)
      {
    sorted_range.push_back(val);
      }
    // ensure the upper_value is contained or surpassed
    sorted_range.push_back(val);
  }
  // to prevent comparison of the entire vector
  bool operator ==(const NumericRange & rhs) const
  {
    return lower == rhs.lower && upper == rhs.upper && delta == rhs.delta;
  }
  // note: this class doesn't really need to store the values in a
  // vector, but it makes the iterator interface much easier.
  const_iterator begin() const
  {
    return sorted_range.begin();
  }
  const_iterator end() const
  {
    return sorted_range.end();
  }
  double get_lower() const
  {
    return lower;
  }
  double get_upper() const
  {
    return upper;
  }
  double get_delta() const
  {
    return delta;
  }
  size_t size() const
  {
    return sorted_range.size();
  }
  void print() const
  {
    std::cout << "[ " << lower << " : " << upper << ": +=" << delta << " ]" << std::endl;
  }
};
我希望我的迭代器与STL迭代器兼容,这样我就可以重用代码(遍历numeriRange应该相当于遍历std::vector)

我已经成功地将值存储在std::vector中(然后使用std::vector的迭代器)。这就是我在网上找到的一切解决这个问题的方法。但是,实际上没有必要存储整个列表

有没有办法避免存储整个值集?是否有一些
iterable
类我可以继承并重写
++
==
等,以在不存储
std::vector
的情况下获得所需的效果?

(我真的很想知道在没有BOOST的情况下如何做到这一点,尽管它很棒。我问这个问题是因为我想学习如何(从头开始)编写类似于BOOST解决方案的东西。我肯定知道软件工程的一部分是使用他人创建的工具,但我真的想学习这些工具是如何设计和构建的。)

我的iterable NumericRange类(在内部使用
std::vector):

double lower = ..., upper = ..., delta = ...;
for (double val = lower; val < upper; val += delta)
{
   // do something with val
   f(val);
}
// include the last val to guarantee upper is included or exceeded
f(val); // do something with val
class NumericRange
{
protected:
  double lower, upper, delta;
  std::vector<double> sorted_range;
public:
  typedef std::vector<double>::const_iterator const_iterator;
  NumericRange()
  {
    lower = upper = delta = std::numeric_limits<double>::quiet_NaN();
    // vector is constructed empty
  }
  NumericRange(double lower_param, double upper_param, double delta_param)
  {
    lower = lower_param;

    upper = upper_param;
    delta = delta_param;
    assert(upper_param > lower_param);

    double val;
    // note: can be much faster without push_back
    for (val = lower_param; val < upper_param; val += delta_param)
      {
    sorted_range.push_back(val);
      }
    // ensure the upper_value is contained or surpassed
    sorted_range.push_back(val);
  }
  // to prevent comparison of the entire vector
  bool operator ==(const NumericRange & rhs) const
  {
    return lower == rhs.lower && upper == rhs.upper && delta == rhs.delta;
  }
  // note: this class doesn't really need to store the values in a
  // vector, but it makes the iterator interface much easier.
  const_iterator begin() const
  {
    return sorted_range.begin();
  }
  const_iterator end() const
  {
    return sorted_range.end();
  }
  double get_lower() const
  {
    return lower;
  }
  double get_upper() const
  {
    return upper;
  }
  double get_delta() const
  {
    return delta;
  }
  size_t size() const
  {
    return sorted_range.size();
  }
  void print() const
  {
    std::cout << "[ " << lower << " : " << upper << ": +=" << delta << " ]" << std::endl;
  }
};
类数值范围
{
受保护的:
双下,上,三角洲;
std::向量排序范围;
公众:
typedef std::vector::const_迭代器const_迭代器;
数值范围()
{
下限=上限=增量=标准::数值限制::安静时间();
//向量是空的
}
数值范围(双下参数、双上参数、双三角参数)
{
下限=下限参数;
上限=上限参数;
delta=delta_参数;
断言(上参数>下参数);
双val;
//注意:无需推回,速度会快得多
对于(val=下参数;val<上参数;val+=增量参数)
{
已排序的范围。推回(val);
}
//确保包含或超过上限值
已排序的范围。推回(val);
}
//防止对整个向量进行比较
布尔运算符==(常量数值范围和rhs)常量
{
返回lower==rhs.lower&&upper==rhs.upper&&delta==rhs.delta;
}
//注意:此类实际上不需要将值存储在
//向量,但它使迭代器接口更容易。
常量迭代器begin()常量
{
返回排序的_范围。开始();
}
常量迭代器end()常量
{
返回排序的_range.end();
}
双get_lower()常量
{
返回较低;
}
双get_upper()常量
{
返回上;
}
双get_delta()常量
{
返回三角洲;
}
大小\u t大小()常量
{
返回排序的_range.size();
}
void print()常量
{
标准::cout
是否有一些iterable类可以继承并重写
++
==
等,以获得所需的效果,而无需存储
std::vector

是的,有。它的名字是
std::iterator

这里是一个开始,使用
int
。为了节省我大脑中的空间,我使用同一个类来表示范围和迭代器

#include <iterator>
#include <iostream>

struct NumericRange : public std::iterator< std::input_iterator_tag, int >
{
  int current, fini, delta;
  typedef NumericRange iterator;
  typedef iterator const_iterator;
  iterator begin() { return *this; }
  iterator end() { return iterator(fini, fini, delta); }
  iterator& operator++() { current += delta; return *this; }
  iterator operator++(int) { iterator result(*this); ++*this; return result; }
  int operator*() const { return current; }
  NumericRange(int start, int fini, int delta) 
    : current(start), fini(fini), delta(delta)
  {
  }
  bool operator==(const iterator& rhs) {
    return rhs.current == current;
  }
  bool operator!=(const iterator& rhs) {
    return !(*this == rhs);
  }
};

void f(int i, int j) {
  std::cout << i << " " << j << "\n";
}

int main () {
  int lower = 4, upper = 14, delta = 5;
  NumericRange nr(lower, upper, delta);
  for (NumericRange::const_iterator iter = nr.begin(); iter != nr.end(); iter++)
  {
      f(*iter, *nr.end());
  }
}
#包括
#包括
struct numeriRange:public std::iterator
{
内流,菲尼,三角洲;
typedef数值范围迭代器;
typedef迭代器const_迭代器;
迭代器begin(){return*this;}
迭代器end(){返回迭代器(fini,fini,delta);}
迭代器和运算符++(){current+=delta;return*this;}
迭代器运算符++(int){迭代器结果(*this);++*this;返回结果;}
int运算符*()常量{return current;}
数值范围(整数开始、整数结束、整数增量)
:当前(开始)、结束(结束)、增量(增量)
{
}
布尔运算符==(常量迭代器和rhs){
返回rhs.current==当前值;
}
布尔运算符!=(常量迭代器和rhs){
返回!(*此==rhs);
}
};
空f(整数i,整数j){

std::cout some,非常感谢。使用
double
有点困难,因为
!=
操作符比较
double
s表示直接相等,这在数字上是危险的。为此,必须保证连续执行
current+=delta
最终将导致
current==fini
;this不一定与
fini=current+k*(delta)相同
其中k是一个整数,因为数字错误。因此,我会在执行
!=
时绑定数字错误并测试该范围内的近似相等性。是的,这就是为什么我从
int
开始的原因。制作一个double版本只是一个练习。出于宗教原因,为什么没有提升呢?@MrLister主要是我这是一个玩笑,但我在上面加了一个说明。好吧。嘿,我并不反对自己做一些事情,而不是使用图书馆。甚至是重新发明轮子,只要它像你说的“作为一个练习”。但是你开始说“宗教原因”所以我想你可能对Boost有一些根本性的问题。你能不能把PPS用粗体字去掉?:)对我来说,这会分散我对其他非常有价值的问题和答案的注意力。@thomastiger说得很好。有很多“你为什么不使用Boost答案?”然后是我试图散布的评论战。但是现在这些评论被删除了,我完全同意你的观点,并且已经编辑过了。