我对范围相当陌生,我想知道是否有一种方法可以应用动态数量的范围适配器。我已经篡改了一些代码有一段时间了,我也做了一些搜索,但没有结果。
#include <iostream>
#include <ranges>
int main() {
auto output = std::ranges::views::iota(2, 100);
for (int i = 2; i < 100; i++) {
output = output | std::ranges::views::filter([i](int num){ return num % i != 0 || num == i; });
}
std::cout << "The 10th prime is: " << output[9] << "\n";
}本质上,我想要这样的东西,但是这会产生一个编译错误(no match for 'operator=')。似乎每个应用程序的范围适配器都需要一个新的类型,所以我们不能动态地创建这个范围。有办法绕过这件事吗?
发布于 2021-12-04 05:22:46
对于这样的固定数目,可以使用元编程递归构建范围(尽管您可能遇到模板实例化深度限制)。您可以通过类型擦除范围来执行真正的动态数字,这样就可以通过虚拟函数调用连接过滤器链。结果是缓慢的,代码是痛苦的,但这当然是可能的。
发布于 2021-12-04 08:14:23
其中一种选择是将每个筛选的结果存储在一个vector中,这将确保每个操作后的范围类型是一致的,并且可以重新分配。
#include <iostream>
#include <ranges>
#include <vector>
auto to_vector(std::ranges::view auto view) {
return std::vector(view.begin(), view.end());
}
int main() {
auto output = to_vector(std::views::iota(2, 100));
for (int i = 2; i < 100; i++) {
output = to_vector(output | std::views::filter(
[i](int num){ return num % i != 0 || num == i; }));
}
std::cout << "The 10th prime is: " << output[9] << "\n";
}但是,这是低效的,也不是使用范围适配器的好用例。因此,您可能需要使用更有效的算法来实现这一点。
发布于 2021-12-04 23:41:29
在这种情况下,您可以构建过滤器谓词:
int main() {
auto output = std::views::iota(2, 100);
std::function<bool(int)> filter_fn = [] (int) { return true; };
for (int i = 2; i < 100; i++)
{
filter_fn = [=] (int num) {
return filter_fn(num) && (num % i != 0 || num == i);
};
}
auto primes = output | std::views::filter(filter_fn);
std::cout << "The 10th prime is: " <<
(primes | std::views::drop(9)).front() << "\n";
}但这并不意味着应该。这是相当低效的,因为它为谓词创建了一系列间接调用。
https://stackoverflow.com/questions/70222956
复制相似问题