gpt4 book ai didi

c++ - 迭代 vector 或数值范围时如何避免代码重复?

转载 作者:行者123 更新时间:2023-12-01 15:13:32 25 4
gpt4 key购买 nike

我需要在循环中执行相当复杂的一段代码,但循环要么在 vector 上,要么在整数的数值范围内。关于循环类型的决定是在运行时做出的:

if(!int_vector_provided){
for(int i=0;i<N;++i){ // iterate over a numeric range
// complex code depending on i
}
} else {
for(int i: int_vector){ // iterate over a vector
// the same complex code
}
}

问题是“复杂代码”很难重构为函数,因为它依赖于许多局部和全局变量。使此代码成为捕获 lambda 也是不可取的,因为这部分对性能至关重要。
如果使用数字范围,它通常非常大(数百万),因此创建此大小的连续数字的 vector 非常低效。

实际上我需要的是一对迭代器,它们可以分配给 vector 的开始/结束或数值范围的开始/结束。就像是:
SomeCleverIterator b,e;

if(int_vector_provided){
b = int_vector.begin();
e = int_vector.end();
} else {
// Iterators to numeric range
// may be boost::counting_range(0,N) ???
// but how to make boost::range iterators and
// to vector<int>::iterator convertible to the same type??
b = ???;
e = ???;
}

for(SomeCleverIterator it=b;it!=e;it++){
// complex code
}

我试着玩 boost::counting_range但它的迭代器不能转换为 vector<int>::iterator所以它没有帮助。

我看到它创建带有迭代器的自定义类模板并为 vector 和整数对显式实例化它的唯一方法,但这对于这种“微不足道”的问题来说似乎有点过分了。

有没有更好的办法?

最佳答案

由于您有不同类型的相同代码,因此需要模板。

并且由于它只会在那个函数中使用,所以通用 lambda 是最方便的:

auto f = [&](auto&& range) {
for (int i : range) {
// complex code depending on i
}
};
if (int_vector_provided)
f(int_vector);
else
f(std::ranges::iota_view(0, N));

我也用过 C++20 std::ranges::iota_view .

当然,这也可能是 flag-envy 的情况,在这种情况下,您应该将接口(interface)拆分为两个不同的函数,可能由一个通用实现支持。

此外,应该最小化全局状态,尤其是可变状态。

关于c++ - 迭代 vector <int> 或数值范围时如何避免代码重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60025321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com