読者です 読者をやめる 読者になる 読者になる

【C++】長いfor文とおさらばだ

C++11の範囲for文を使ったらSTLのコンテナを簡単に回せる

std::vector<int> v;
// C++03
for(int i = 0 ; i < v.size() ; i++)
{
    v[i];
}
// algorithm
std::for_each(v.begin(),v.end(),func);
// C++11
for(auto it : v)
{
    it;
}

見やすくて書きやすい

だけど、結局 Index がほしい場合、どうしても昔の書き方に戻ってしまう

悔しいので範囲for文について調べ Index を回すクラスを作成してみた

#include <stdexcept>  // std::out_of_range
#include <limits.h>   // INT_MAX
#include <vector>     // std::vector
#include <iostream>   // std::cout / std::endl
class Range
{
public:
    // [start...start+count)
    Range(int start,int count):index_(start),max_(start+count)
    {
        if(count < 0) throw std::out_of_range("count is less than 0.");
    }
    // [0...count)
    Range(int count):Range(0,count){}
    // ↓イテレータの条件を満たす↓
    int operator*(){return index_;}
    void operator++(){++index_;}
    bool operator != (Range&){return index_ < max_;}
    // ↓範囲for文の条件を満たす↓
    Range begin() const {return *this;}
    Range end() const {return *this;}
private:
    int index_;
    int max_;
};

使い方

std::vector<int> v{10,20,30,40};
// [0...size)
for(auto i : Range(v.size()))
{
    std::cout << v[i] << ",";
}
std::cout << std::endl;
// [2...2+4)
for(auto i : Range(2,4))
{
    std::cout << i << ",";
}
出力
10,20,30,40,
2,3,4,5,

長いforはもう書かなくて済みます

参考したサイト
範囲for文を自作クラスで使う - 誤解を恐れずに言うと云々