2016-09-14 112 views
3

我有一些代码,列举了一些数据,这样的事情:从整数索引的for循环枚举范围换

int count; 
InitDataEnumeration(/* some init params */, &count); 

for (int i = 0; i < count; i++) 
{ 
    EnumGetData(i, &data); 
    // process data ... 
} 

我想此代码转换以适合℃的形式++ 11的范围为

我正在考虑定义一个DataEnumerator包装类,它的构造函数会调用上面的InitDataEnumeration()函数。

的想法是使用包装类是这样的:

DataEnumerator enumerator{/* init params*/}; 

for (const auto& data : enumerator) 
{ 
    // process data ... 
} 

怎么能-indexed for循环前者int后者基于范围的形式进行重构?

我在想从枚举器封装类中暴露begin()end()方法,但我不知道它们应该返回哪种类型的迭代器,以及如何定义这样的迭代器。

请注意,迭代过程是仅向前的。

+0

我不明白在“重复”链接问题中给出了我的问题的答案。 –

回答

0

你是正确约begin()end(),不管他们返回应提供:

  • 操作++(前缀只就够了)
  • 运营商=
  • 符*

所有漂亮!不言自明的。

请注意,不需要任何特征或类别,对于用于某些标准库算法的迭代器而言,这只是最低限度。

1

您需要输入迭代器这个例子从http://en.cppreference.com/w/cpp/iterator/iterator完全复制:

#include <iostream> 
#include <algorithm> 

template<long FROM, long TO> 
class Range { 
public: 
    // member typedefs provided through inheriting from std::iterator 
    class iterator: public std::iterator< 
        std::input_iterator_tag, // iterator_category 
        long,      // value_type 
        long,      // difference_type 
        const long*,    // pointer 
        long      // reference 
            >{ 
    long num = FROM; 
    public: 
    explicit iterator(long _num = 0) : num(_num) {} 
    iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;} 
    iterator operator++(int) {iterator retval = *this; ++(*this); return retval;} 
    bool operator==(iterator other) const {return num == other.num;} 
    bool operator!=(iterator other) const {return !(*this == other);} 
    reference operator*() const {return num;} 
    }; 
    iterator begin() {return iterator(FROM);} 
    iterator end() {return iterator(TO >= FROM? TO+1 : TO-1);} 
}; 

int main() { 
    // std::find requires a input iterator 
    auto range = Range<15, 25>(); 
    auto itr = std::find(range.begin(), range.end(), 18); 
    std::cout << *itr << '\n'; // 18 

    // Range::iterator also satisfies range-based for requirements 
    for(long l : Range<3, 5>()) { 
    std::cout << l << ' '; // 3 4 5 
    } 
    std::cout << '\n'; 
} 
+1

因为这是复制材料,所以我将编辑回滚到引号,并且应该标记为 – NathanOliver

+2

还要注意,这是一个模板,因此它只在编译时知道大小时才起作用。如果它依赖于运行时间,这将不起作用。 – NathanOliver

2

你在找什么可以boost::irange完成。它会构建一个范围在[first, last)范围内的整数,你可以直接放入它,就像在for循环中使用i一样。

for (int i = 0; i < count; i++) 
{ 
    EnumGetData(i, &data); 
    // process data ... 
} 

变为

for (auto i : boost::irange(0, count)) 
{ 
    EnumGetData(i, &data); 
    // process data ... 
} 
+0

对不起,但这并没有增加任何好的索引。请查看我的第二个代码段,了解所需的代码。 –

-1

for(auto x : y)这里,y必须是具有一个begin()方法和end()方法,每个返回一个实现迭代器的概念的对象的类的对象。迭代器必须是可增量的(iter++),必须能够准确地确定它是否等于另一个相同类型的迭代器(通过!=),并且必须取消引用任何x需要的值。

这是你应该考虑做的事情,如果你或者A)无聊或者没有其他更好的事情或者B)有合理的需要。虽然这不难做到,但这也不是微不足道的。