mid*_*dor 10 c++ iterator generator functor
我有一个问题,很可能之前就是这样问的,因为我认为我想要的东西是很多人想要的.但是,我无法想出任何方式表达它会返回我想要的搜索(不是谷歌,不是这里).所以这里的答案可能只是用来描述我的意思的单个术语.
我想要实现的是大致如下的内容:
它可以采用仿函数struct/class,并根据仿函数的函数为所述仿函数生成一系列值.应该可以使用有状态仿函数,即应该可以在状态a中实例化仿函数并使其运行直到它处于状态b,生成值范围{f(a),f(a + 1) ,...,f(b)},其中f(a + 1)表示由f表示的系列中的下一个项目.
它的行为类似于迭代器,即它可以传递而不是迭代器,例如用值填充向量.
我认为名称应该是生成器或生成迭代器,因为它就是它的作用,但是我在查找具有该术语的内容时非常失败.我已经编写了自己的实现,但它有它的问题,我想问一下,如果有更多的努力之前有这样的事情.
为了节省你粘贴所有后续代码的工作,以防你想尝试这个,我把它放在ideone上.我认为在运行代码后很清楚它的作用.
我当前的实现看起来像这样(fyi这是一个缩短的版本,其中有些东西像 - 和 - 缺失,所以我确实实现了它们,因此它至少可以作为双向迭代器工作.我也有一个[]函数,所以我想把它变成random_access.):
template <class F>
class generator{
public:
//typedefs required for iterator-use
typedef typename F::value_type value_type;
typedef typename F::step_type step_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef typename F::size_type size_type;
typedef typename F::difference_type difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
generator(value_type init, step_type step) : t(init), step(step){}
generator<F> &operator++() {
t += step; return *this;
}
generator<F> &
operator+=(size_type n)
{
t += n * step;
return *this;
}
generator<F>
operator+(size_type n)
{
return generator(*this) += n;
}
value_type operator*() const {
return f(t);
}
value_type operator*() const {
return f(t);
}
friend bool operator==(const generator<F> &lhs, const generator<F> &rhs){
return lhs.t == rhs.t;
}
friend bool operator!=(const generator<F> &lhs, const generator<F> &rhs){
return !(lhs == rhs);
}
private:
value_type t;
value_type step;
F f;
};
Run Code Online (Sandbox Code Playgroud)
我使用不同的模板尽可能容易地提供typedef:
template <typename T>
struct simple_generator_function
{
typedef T value_type;
typedef T step_type;
typedef T difference_type;
typedef size_t size_type;
};
Run Code Online (Sandbox Code Playgroud)
现在这两个与一个具体的"发电机"一起工作,如下所示:
template <typename T>
struct square_generator : public simple_generator_function<T> {
T operator()(T t) const{
return t * t;
}
};
int main(void) {
using int_sqg = generator<square_generator<int>>;
//starting at initial value 1 take steps of size 4
int_sqg gen(1, 1);
//fill with all before inital + n * step
vector<int> v(gen, gen+10);
copy(begin(v), end(v), ostream_iterator<int>(cout, ","));
cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)
长话短说:是否有一个提升或其他库,它以一种可靠的方式提供这个,这样的迭代器/仿函数混合的名称一般是什么?
编辑1:
我认为任何解决方案充其量只能是一个InputIterator,因为据我研究过,所有其他迭代器都必须从operator*()返回一个引用,在这种情况下这是不可能的.很可能,它归结为编写一个将常规仿函数转换为InputIterator的模板.
现状:到目前为止的答案还不错,但是我在考虑之前已经考虑了很长一段时间,而且我考虑过类似的解决方案,所以我的问题没有得到真正的回答.我已经更新了要求1.) - 希望 - 更清楚地反映我想要的东西.如果没有任何结果,我可能会尝试将我当前的代码改进为更稳定的版本并将其放在github上.
编辑2(赏金结束):
尽管我对解决方案并不完全满意,但是将boost :: irange与boost :: transform结合起来作为ectamur建议最接近做我想要的,所以我会给他赏金.
解决此问题的Boost.Range方法是使用transform迭代器适配器:
auto rng = boost::irange(1, 10)
| boost::adaptors::transformed([](int i) { return i * i; });
std::vector<int> v{rng.begin(), rng.end()};
Run Code Online (Sandbox Code Playgroud)
请注意这是如何将转换的关注点与输入范围的开始/停止/步骤(可选)参数区分开来的.
C++ 库已经提供了一些算法,可以实现您尝试自己完成的大部分功能。我认为您最好调整您的模板,以便它可以与 C++ 库无缝协作。
我正在特别考虑std::generate()。
因此,您将执行步骤 #1 中计划执行的操作,但将步骤 #2 替换为实现operator()返回序列中下一个值的 。
然后,您可以让std::generate() 负责用您的值填充实际序列。