簡體   English   中英

從整數索引for循環枚舉到range-for

[英]From integer-indexed for loop enumeration to range-for

我有一些代碼列舉了一些數據,如下所示:

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

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

我想以適合C ++ 11 范圍的形式轉換此代碼。

我在考慮定義一個DataEnumerator包裝類,其構造函數將調用上面的InitDataEnumeration()函數。

想法是使用這樣的包裝類:

DataEnumerator enumerator{/* init params*/};

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

如何在后一個基於范圍的形式中重構前一個int -indexed for循環?

我正在考慮從枚舉器包裝類中公開begin()end()方法,但我不知道它們應該返回什么類型的迭代器,以及如何定義這樣的迭代器。

請注意,迭代過程僅向前。

您正在尋找的是可以使用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 ...
}

您需要一個輸入迭代器,此示例完全從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'; } 

你對begin()end()看法是正確的,無論它們返回應該提供什么:

  • operator ++(僅前綴就足夠了)
  • 運算符!=
  • 運營商*

一切都不言自明。

請注意,不需要任何特征或類別,就像用於某些標准庫算法的迭代器一樣 - 只是最低限度。

for(auto x : y)這里, y必須是一個類的對象,該類具有begin()方法和end()方法,每個方法都返回一個實現迭代器概念的對象。 迭代器必須是可遞增的( iter++ ),必須能夠准確地確定它是否等於同一類型的另一個迭代器(通過!= ),並且必須取消引用任何需要的x

如果您要么A)感到無聊或者沒有其他更好的事情要做,或者B)有合法需要,那么您應該考慮這樣做。 雖然這不難做到,但也不是微不足道的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM