你打算如何处理迭代值?
如果这将是数组中的某个索引,您应该使用相关iterator
或reverse_iterator
类,并围绕这些实现您的算法。您的代码将更加健壮,并且更易于维护或发展。此外,标准库中的很多工具都是使用这些接口构建的。
实际上,即使你不这样做,你也可以实现一个返回自己索引的迭代器类。
您还可以使用一点元编程魔法来定义您的迭代器将如何根据A
and的顺序运行B
。
在继续之前,请考虑这仅适用于和的常数值。A
B
template <int A,int B>
struct ordered {
static const bool value = A > B ? false: true;
};
template <bool B>
int pre_incr(int &v){
return ++v;
}
template <>
int pre_incr<false>(int &v){
return --v;
}
template <int A, int B>
class const_int_iterator : public iterator<input_iterator_tag, const int>
{
int p;
public:
typedef const_int_iterator<A,B> self_type;
const_int_iterator() : p(A) {}
const_int_iterator(int s) : p(s) {}
const_int_iterator(const self_type& mit) : p(mit.p) {}
self_type& operator++() {pre_incr< ordered<A,B>::value >(p);return *this;}
self_type operator++(int) {self_type tmp(*this); operator++(); return tmp;}
bool operator==(const self_type& rhs) {return p==rhs.p;}
bool operator!=(const self_type& rhs) {return p!=rhs.p;}
const int& operator*() {return p;}
};
template <int A, int B>
class iterator_factory {
public:
typedef const_int_iterator<A,B> iterator_type;
static iterator_type begin(){
return iterator_type();
}
static iterator_type end(){
return iterator_type(B);
}
};
在上面的代码中,我定义了一个iterator
从 A 到 B 的值的准系统类。有一个简单的元编程测试来确定 A 和 B 是否按升序排列,并选择正确的运算符 ( ++
or --
) 来遍历这些值。
最后,我还定义了一个简单的工厂类来保存begin
和end
迭代方法,使用这个类可以让你的依赖类型值 A 和 B 只有一个声明点(我的意思是你只需要使用 A 和 B 一次这个容器,以及从那里生成的迭代器将取决于这些相同的 A 和 B,从而在一定程度上简化了代码)。
这里我提供一个简单的测试程序,输出值从 20 到 11。
#define A 20
#define B 10
typedef iterator_factory<A,B> factory;
int main(){
auto it = factory::begin();
for (;it != factory::end();it++)
cout << "iterator is : " << *it << endl;
}
不过,使用标准库可能会有更好的方法来做到这一点。
使用O
and UINT_MAX
for A
and的问题B
被提出来了。我认为应该可以通过使用这些特定值重载模板来处理这些情况(留给读者作为练习)。