So-net無料ブログ作成

数値のイテレータ化 [プログラミング]

vector0 から 9 までの数値を格納しようとする場合、次の様なコードを書きます。

std::vector<int> array;
for (int i = 0; i < 10; i++)
    array.push_back(i);

ところで、値が既に配列に入っている場合は、こんなにシンプルに書くことが出来ます。

int buff[10] = { (略) };

std::vector<int> array(buff, buff + 10);

配列を使わなくても、同じ様にシンプルに書けないものかな……。

要は、数値、というか数値型の変数intをイテレータとして解釈できれば良いわけですよ。

イテレータとしての最低限の要件は…

  • ++演算子で次の値を指すようになる。
  • *演算子で現在の値を表す。

と言うことで、int型の変数が、この要件も満たすかというと……。

int n = 0;

++n;    // nが、次の値 (1) を表すようになる。OK
*n;     // 文法 エラー

やっぱり無理でした。

そんなわけで、数値をイテレータの様に使うためのラッパクラスを作ってみました。

#include        <boost/operators.hpp>

template<typename T, T U>
class value_iterator :
        public boost::random_access_iterator_helper<value_iterator<T, U>,
                                                                   T,
                                                                   std::ptrdiff_t,
                                                                   T,
                                                                   T&>
{
  private:
    T value_;

  public:
    typedef value_iterator<T, U> self;
    typedef std::ptrdiff_t difference_type;
    typedef T& reference;
    typedef const T& const_reference;
    
    value_iterator(T value) : value_(value)
    {
    }

    bool operator==(const self& rhs) const
    {
        return value_ == rhs.value_;
//        return std::abs(value_ - rhs.value_) < U;
    }
    
    bool operator<(const self& rhs) const
    {
        return value_ < rhs.value_;
//        return value_ - rhs.value_ <= -U;
    }
    
    self& operator++()
    {
        value_ += U;
        return *this;
    }

    self& operator--()
    {
        value_ -= U;
        return *this;
    }

    self& operator+=(difference_type diff)
    {
        value_ += U*diff;
        return *this;
    }

    self& operator-=(difference_type diff)
    {
        value_ -= U*diff;
        return *this;
    }

    reference operator*()
    {
        return value_;
    }

    const_reference operator*() const
    {
        return value_;
    }

    difference_type operator-(const self& rhs) const
    {
        return (value_ - rhs.value_) / U;
    }
};

使うためには、boostが必要です(無くても、ちょっと修正するだけで使えます)

使い方は、こんな感じです。

// vector に 0 ~ 9 を格納する。

typedef value_iterator<int, 1> it1;

std::vector<int> array(it1(0), it1(10));

テンプレートの2つ目の数字は、++ した時に増える数字なので、こんな使い方も可能です。

// vector に 0 ~ 9 を1つおきに格納する。

typedef value_iterator<int, 2> it2;

std::vector<int> array(it2(0), it2(10));
[新幹線] 今日の一冊
魔術師 (イリュージョニスト)

魔術師

  • 作者: ジェフリー・ディーヴァー
  • 出版社/メーカー: 文藝春秋
  • 発売日: 2004/10/13
  • メディア: 単行本

タグ:C++
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。