【发布时间】:2015-03-31 12:53:11
【问题描述】:
我有一个问题,很可能以前有人问过这个问题,因为我认为我想要的是相当多的人想要的东西。但是我想不出任何表达方式来返回我想要的搜索结果(不是谷歌,不是这里)。所以也许这里的答案只是用来描述我的意思的一个术语。
我想要实现的是大致执行以下操作:
它可以采用函子结构/类并生成一系列值 基于函子的函数的所述函子。应该可以使用有状态函子,即应该可以在状态 a 中实例化函子并让它运行直到它处于状态 b,生成值范围 {f(a), f(a+1) , ..., f(b)},其中 f(a+1) 表示 f 表示的系列中的下一项。
它的行为类似于迭代器,即它可以被传递而不是迭代器,例如用值填充向量。
我认为名称应该是生成器或生成迭代器,因为它就是这样做的,但我一直没有成功找到带有该术语的东西。我已经编写了自己的实现,但它有它的问题,我想问一下,在投入更多精力之前是否有这样的事情。
为了节省您粘贴所有后续代码的工作,以防您想尝试一下,我把它放在ideone 上。我想在运行代码之后,它的作用就很清楚了。
我当前的实现看起来像这样(仅供参考,这是一个缩短的版本,其中缺少一些像 - 和 - 这样的东西,所以是的,我确实实现了它们,因此它至少可以作为双向迭代器工作。我还有一个[] 函数,所以我考虑将其设为 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;
};
我使用不同的模板来尽可能轻松地提供 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;
};
现在这两者与一个具体的“生成器”一起工作,如下所示:
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';
}
长话短说:是否有 boost 或其他库,它以某种可靠的方式提供了这一点,这种迭代器/仿函数组合的一般名称是什么?
编辑 1:
我认为任何解决方案充其量只能是 InputIterator,因为据我研究,所有其他迭代器都必须从 operator*(),在这种情况下是不可能的。很可能归结为编写一个将常规函子转换为 InputIterator 的模板。
状态:到目前为止的答案都很好,但是在提问之前我已经考虑了很长时间,并且我已经考虑过类似的解决方案,所以我的问题没有得到真正的回答。我已经更新了要求 1.) 以 - 希望 - 更清楚地反映我想要的。如果没有任何结果,我可能会尝试将我当前的代码改进为更稳定的版本并将其放在 github 上。
编辑 2(赏金结束):
尽管我对解决方案并不完全满意,但 boost::irange 与 ectamur 建议的 boost::transformed 相结合最接近于做我想做的事情,所以我会给他赏金。
【问题讨论】:
-
类似,但 function_input_iterator 似乎很难使用。我的意思是我知道我可以通过创建来创建函数,例如一个 square_gen ,我使用 bind 来修复步长并将其作为模板参数传递,但是一直使用 make_function_input_iterator 似乎很不方便。现在我可以只使用 operator+、operator- 甚至 operator[] 之类的东西,我想保持这种灵活性。
-
顺便说一句,现在可以使用协程正确实现。我知道这个问题与人们的相关性有多大,所以如果它仍然对评论进行投票,如果它达到 5,我会详细说明,否则让这个问题不活跃并死掉。
标签: c++ iterator generator functor