こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

std::for_eachに、ループカウンタを入れる方法。

表題の通りなのですが、次のようなループのカウンタを呼び出される
配列に入れるにはどうしたらいいのでしょうか?

const int MAX = 100;
int Array[MAX] = {0};
/*
//これと同じことをしたいのですが。。。。
for( int i=0; i<MAX; ++i )
 Array[i] = i;
*/
for_each(Array, Array+MAX, /*ここはどうするのでしょう?*/);

調べてみましたが、めぼしいものがみつかりません。
もともと無理なものなのでしょうか?
ご教授お願いします。環境はVC8です。

投稿日時 - 2008-12-04 21:34:56

QNo.4530138

すぐに回答ほしいです

質問者が選んだベストアンサー

 こんばんは。

 関数オブジェクトが一番楽です。

struct CCounter
{
CCounter() : m_iRef(0)
{}

void operator()(int& rVal)
{
rVal = m_iRef++;
}

private:
int m_iRef;
};

static void Print(int iVal)
{
cout << iVal << endl;
}

int main(void)
{
const int MAX = 100;
int Array[MAX] = {0};

std::for_each(Array, Array+MAX, CCounter());
std::for_each(Array, Array+MAX, &::Print);

return 0;
}

投稿日時 - 2008-12-04 22:05:10

お礼

早速の回答ありがとうございます。
やはり、明示的に引数にループカウンタを入れるのは無理なので
自分で、カウンタを模したものを、入れるしかないのですね。。。

投稿日時 - 2008-12-04 22:59:13

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

> 配列のindexに依存するようなコードを書くのがもう時代遅れ
> だということを暗に意味しているのでしょうかね?

時代遅れということはないと思いますが、STLの方針には合わないということでしょう。
添え字を使う場合、配列、vector、deque、basic_stringなどは問題ないですが、listやsetなどでは無理があります。

投稿日時 - 2008-12-05 09:47:01

ANo.2

VC++8に現物合わせするのであれば#1の回答で問題ありません。
しかし、(VC++の将来のバージョンを含めて)他の処理系との移植性を考える場合は適切とはいえません。

まず、for_eachはInputIteratorを要求しますので、その参照先を更新することはできません。更新が必要な場合は、generateなど、他のアルゴリズムを使用すべきです。

次に、状態を持つ関数オブジェクトは、アルゴリズム関数の中で複数回コピーされる可能性があることに注意しなければなりません。常に同じインスタンスを用いて処理できるのであればよいのですが、規格上そのような保証はありません。

また、for_eachの場合、範囲内の各要素に対して前から順に操作することが規定されていますが、generateなどではその規定がありません。すなわち、呼び出される順序に依存する関数オブジェクトは適切ではありません。

つまり、一般的には無理だと思います。

投稿日時 - 2008-12-04 23:27:44

お礼

回答ありがとうございます。
その点はまさに、気になっていたことです!!
やはり現時点での間に合わせに過ぎないのですね。
配列のindexに依存するようなコードを書くのがもう時代遅れ
だということを暗に意味しているのでしょうかね?

投稿日時 - 2008-12-04 23:33:09