[英]C++ std::iterator without using std::vector or std::list internally
我正在嘗試(作為練習)在C ++中創建一個簡單的數值范圍類。 它會讓你迭代均勻間隔的雙精度(如numpy / Python arange
):
我想做什么(但使用迭代器):
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
期望的等效迭代器代碼:
double lower = ..., upper = ..., delta = ...;
NumericRange nr(lower, upper, delta);
for (NumericRange::const_iterator iter = nr.begin(); iter != nr.end(); iter++)
{
f(*iter);
}
我希望我的迭代器與STL迭代器兼容,所以我可以重用代碼(迭代通過NumericRange應該相當於迭代通過std :: vector)。
我只是成功地將值存儲在std :: vector中(然后使用std :: vector的迭代器)。 這就是我在網上發現的一切都解決了這個問題。 但是,實際上沒有必要存儲整個列表。
有沒有辦法避免存儲整個值集? 是否有一些iterable
類我可以繼承並覆蓋++
, ==
等以獲得所需的效果而不存儲std::vector<double>
?
(我真的很想知道如何在沒有BOOST的情況下做到這一點,即使它很棒。我問這個是因為我想學習如何寫 (從頭開始)像BOOST解決方案。我當然知道那部分軟件工程正在使用其他人創建的工具,但我真的想了解這些工具是如何設計和構建的。)
我的可迭代NumericRange類(在內部使用std::vector<double>
):
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::vector<double>
?
就在這里。 它的名字是std::iterator<std::input_iterator_tag, double>
。
這是一個使用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());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.