[英]Range-based loop use another operator
我有一个素数生成器,基于我在Eratosthenes的Sieve中在python中看到的内容,因此该生成器基本上生成具有良好性能的素数。
我想要的是在素数范围内使用基于范围的循环,所以这是我所做的:
//Consider prime_generator a class with both operator*, operator!= and operator< overloaded
class primes_range {
private:
unsigned int max;
public:
primes_range(unsigned int max) : max(max) {}
prime_generator begin() const {
return prime_generator(); //so this generator begin from 2 to
//infinity and beyond but of course
//all primes
}
prime_generator end() const {
prime_generator result;
for (:*result < max; ++result) {} //so this thing actually create a
//generator and increment it until it
//gives the first prime number
//above max so it basically do
//all the work that I don't
//want it to do now
return rest;
}
};
因此,在我的主要文章中,我想使用基于范围的循环,这就是primes_range类的重点。
int main() {
for (auto && i : primes_range(10)) { //So here, this is silly because
//the range-based loop will use end()
//wich will calculate all the prime
//numbers at the very beginning
//and i will increment apart from
//this starting process
cout << i << endl;
}
return 0;
}
当然,我可以使用一个简单的循环:
int main() {
for (prime_generator pg; *pg < 10; ++pg) {
cout << *pg << endl;
}
return 0;
}
但是,由于范围基循环更易于阅读并且禁止使用运算符*,因此我想改用它,所以我的问题是:有没有一种方法可以使范围基循环使用比!=(在这种情况下<)? 也许覆盖了primes_range的特定功能或专门设计了比较器?
迭代器必须在每次对operator++
调用时生成下一个素数,然后在对operator*
的调用中返回它们,而不是对end()
方法进行全部工作。 因此,您的迭代器类的方案可能是:
class prime_generator {
typedef std::forward_iterator_tag iterator_category;
int cur;
prime_generator& operator++() {
cur = GenerateNextPrime();
return *this;
}
int operator*() {
return curr;
}
};
笔记:
operator++
和operator*
。 forward_iterator_tag
告诉您正在创建哪种迭代器。 在这种情况下,前向迭代器是一种通过operator++
“获取下一个”操作的operator++
但例如不通过索引进行随机访问。 最好在迭代器类中声明此类别字段,以提示有关与迭代器一起使用的最佳算法的标准库方法。 这是关于迭代器的完整示例。 我在上面忘了提到您需要使用operator!=
来工作的range based for
因为它必须将当前迭代器与end()
方法的结果进行比较。 在下面的代码中,您只需要将正确的算法实现放置在generate_next_prime
函数中,或根据需要将其放置在casse中即可。
#include <iostream>
#include <iterator>
int generate_next_prime(int previous) {
// TODO: a correct one!
return previous + 1;
}
class prime_generator {
int limit;
public:
prime_generator(int limit)
: limit(limit) {}
class iterator {
int cur, limit;
public:
typedef std::forward_iterator_tag iterator_category;
iterator(int cur, int limit)
: cur(cur), limit(limit) {}
iterator& operator++() {
cur = generate_next_prime(cur);
return *this;
}
bool operator==(const iterator &other) {
// NOTE: for the primes application maybe you should
// use >= instead of == to ensure cur will not pass limit
// silently, or do something more elaborate
return cur == other.cur &&
limit == other.limit;
}
bool operator!=(const iterator &other) {
return !(*this == other);
}
int operator*() {
return cur;
}
};
iterator begin() {
return iterator(2, limit);
}
iterator end() {
return iterator(limit, limit);
}
};
int main() {
for (auto p : prime_generator(5))
std::cout << p << std::endl;
return 0;
}
根据您告诉我的内容,我来介绍一种解决方案,它基本上是一个适配器。
class primes_range {
private:
unsigned int max;
class limited_prime_generator {
private:
prime_generator pg;
unsigned int limit;
bool reachedLimit;
public:
limited_prime_generator(unsigned int limit, bool reachedLimit = false) : pg(), limit(limit), reachedLimit(reachedLimit) {}
limited_prime_generator & operator++() {
if (not reachedLimit) {
reachedLimit = *(++pg) >= limit;
}
return *this;
}
bool operator!=(limited_prime_generator const & lpg) const {
return operator*() != *lpg;
}
unsigned int operator*() const {
if (reachedLimit)
return limit;
else
return *pg;
}
};
public:
primes_range(unsigned int max) : max(max) {}
limited_prime_generator begin() const {
return limited_prime_generator(max);
}
limited_prime_generator end() const {
return limited_prime_generator(max, true);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.