我有一个素数生成器,它基于我在 Python 中看到的 Eratosthenes 的 Sieve,所以这个生成器基本上可以生成具有良好性能的素数。
我想要的是在一系列质数上使用基于范围的循环,所以这就是我所做的:
//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++
时生成下一个素数,而不是在 end()
方法上完成所有工作,然后在对运算符*
。所以你的迭代器类的方案可能是:
class prime_generator {
typedef std::forward_iterator_tag iterator_category;
int cur;
prime_generator& operator++() {
cur = GenerateNextPrime();
return *this;
}
int operator*() {
return curr;
}
};
注意事项:
- 要使基于范围的 for 工作,您的迭代器类至少需要
operator++
和operator*
,并具有上述签名。 - 在迭代器类中声明的
forward_iterator_tag
告诉您正在创建哪种迭代器。在这种情况下,前向迭代器是通过operator++
支持“获取下一个”操作但不支持通过索引进行随机访问的迭代器。最好在迭代器类中声明此类别字段,以提示标准库方法关于与迭代器一起使用的最佳算法。
关于c++ - 基于范围的循环使用另一个运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41977956/