c++ - 一种后增量运算符,允许在指定的步长上进行增量
问题描述
哪个更糟?
创建副本
#include <vector>
#include <algorithm>
template<class T>
std::vector<T> range(const T start, const T stop, const T step) {
int leaps = ((stop-start)/step);
std::vector<T> output(leaps > 0 ? leaps : -leaps);
std::generate(output.begin(), output.end(), [i = start, step] () mutable {
T num = i;
i+=step;
return num;
});
return output;
}
或重复(我假设一个计算)。
#include <vector>
#include <algorithm>
template<class T>
std::vector<T> range(const T start, const T stop, const T step) {
int leaps = ((stop-start)/step);
std::vector<T> output(leaps > 0 ? leaps : -leaps);
std::generate(output.begin(), output.end(), [i = start-step, step] () mutable {return i+=step;});
return output;
}
有没有办法避免两者?诸如后增量运算符之类的东西,其行为类似于i++
但允许增量step
.
// Example
int main() {
std::vector<double> check_range = range(-4.13, 2.13, 0.25);
return 0;
}
预期的
-4.13, -3.88, -3.63, -3.38, -3.13, -2.88, -2.63, -2.38, -2.13, -1.88, -1.63, -1.38, -1.13, -0.88, -0.63, -0.38, -0.13, 0.12, 0.37, 0.62, 0.87, 1.12, 1.37, 1.62, 1.87
解决方案
在 C++20 中,我会懒惰地写它:
template <class T>
auto range(const T start, const T stop, const T step) {
return views::iota(0)
| views::transform([=](int i) -> T{
return i * step + start;
})
| views::take_while([=](T cur){
return cur < stop;
});
}
如果您真的想要 a vector
,您可以急切地评估它,但您可能不需要一次全部?
您还可以使用协程编写生成器(虽然generator<T>
不在标准库中,但需要像 cppcoro 一样使用):
template <class T>
generator<T> range(T start, const T stop, const T step) {
for (; start < stop; start += stop) {
co_yield start;
}
}
vector
同样,它是一个惰性范围,如果您真的想要,可以急切地将其评估为 a 。