melt日記

.NETすらまともに扱えないへたれのページ

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  111  : 記事  3  : コメント  8241  : トラックバック  41

ニュース

わんくま同盟

わんくま同盟

C# と VB.NET の質問掲示板

iKnow!


Dictation



書庫

[C++]for each の続き

 

CountEnumerable みたいな、自分が何番目の値かを知ることが出来る iterator が欲しくなってきたので、for each で実装できるような形で作ってみました。

// 値にカウントをくっつけたクラス
template<class TValue>
class loop_count_value
{
public:
    TValue& value;
    int count;
 
    loop_count_value(loop_count_value& v)
        : value(v.value), count(v.count) { }
    loop_count_value(TValue& v, int c)]
        : value(v), count(c) { }
};
 
// イテレータにカウントをくっつけたクラス
template<class TIter, class TValue>
class loop_count_iterator
{
    int count;
 
public:
    TIter iter;
 
    loop_count_iterator(TIter iter_, int count_ = 0)
        : iter(iter_), count(count_) { }
 
    // 最低限必要なメソッドだけ用意する
 
    // インクリメント
    loop_count_iterator& operator++()
    {
        ++iter;
        // ++ されたらカウントを増やす
        ++count;
        return *this;
    }
 
    // 比較
    bool operator!=(const loop_count_iterator& right) const
    {
        return (iter != right.iter);
    }
 
    // 値の取り出し
    loop_count_value<TValue> operator*() const
    {
        return loop_count_value<TValue>(*iter, count);
    }
};
 
// カウント付きイテレータを返す、イテレート可能なクラス
template<class TColl>
class loop_count_iteratable
{
private:
    TColl& coll;
public:
    typedef typename TColl::iterator iterator;
    typedef typename TColl::value_type value_type;
 
    loop_count_iterator<iterator, value_type> begin() const
    {
        return loop_count_iterator<iterator, value_type>(coll.begin());
    }
    loop_count_iterator<iterator, value_type> end() const
    {
        return loop_count_iterator<iterator, value_type>(coll.end());
    }
 
    loop_count_iteratable(TColl& coll_)
        : coll(coll_) { }
};
 
// loop_count_iteratable を簡単に書くためのヘルパ
template<class TColl>
loop_count_iteratable<TColl> loop_count(TColl& iteratable)
{
    return loop_count_iteratable<TColl>(iteratable);
}

テスト

std::vector<int> v;
v.push_back(8);
v.push_back(9);
v.push_back(3);
for each (loop_count_value<int> value in loop_count(v))
{
    std::cout << "[" << value.count << "] = " << value.value << std::endl;
}

実行結果

v[0] = 8
v[1] = 9
v[2] = 3

便利……なのか?

投稿日時 : 2007年9月25日 18:01

コメント

# re: [C++]for each(2) 2007/09/26 11:54 επιστημη
std::vector<std::string> v;
...
int i = 0;
// loop_countはコンテナとint&を受け取る。++のついでにint&を++する。
for each ( std::string value in loop_count(v,i)) {
 std::cout << '[' << i << "] = " << value << std::endl;
}

なんてのはいかがざんしょ。


# re: [C++]for each(2) 2007/09/26 13:59 melt
それいいですねーw
ちょっと実装してみますw

# re: [C++]for each(2) 2007/09/26 15:46 アキラ
for eachは参照使えないので実は遅いです
組み込み型以外には使いたくないですね

for each(const widget& value in v);
↑これができない

BOOST_FOREACHも値渡しするとfor eachと同じくらいの速度で、(const)参照でやるとfor文よりちょっと遅い程度

# re: [C++]for each(2) 2007/09/26 15:53 アキラ
あ、VC++9.0(2008)だと参照使えますね

失礼しました。

# [C++]for each(3) 2007/09/26 15:54 melt日記
[C++]for each(3)

# [C++]for each(3) 2007/09/26 15:56 melt日記
[C++]for each(3)

# re: [C++]for each(2) 2007/09/26 16:03 アキラ
すいません。やっぱり参照は使えないです。
でも、const参照は使えます(そっちだと速い)

# re: [C++]for each(2) 2007/09/26 18:22 MB
参照は
標準コンテナでなければ?使えるんじゃないでしょうか

for each(int &x, boost::make_iterator_range(v)) {}

のようになんらかのラッパーを挟むと。

Post Feedback

タイトル
名前
Url:
コメント