3

すなわち

int ToBeFilled[10];
int GenerateSomething(int x);
for(int i = 0; i < 10; ++i) ToBeFilled[i] = GenerateSomething(i);

std::fill() を使用してそれを行う方法は?

std::fill(ToBeFilled, ToBeFilled + sizeof(ToBeFilled), GenerateSomething(/*How to do?*/));

////
更新:

は、実際にはのGenerateSomething(i)ようなポインタを返す関数呼び出しpObj->GetIt(i)です。通常は特定のポインタが 1 つだけ必要なので、 のように使用しpObj->GetIt(0)ますが、ループが発生するようにすべてのポインタを取得する必要がある場合もあります。

4

2 に答える 2

4

さらに別の、わずかに異なる(そしてC ++ 11のみ)アプローチ:

using std::begin;
using std::end;

std::iota(begin(toBeFilled), end(toBeFilled), 0);

std::transform(begin(toBeFilled), end(toBeFilled), 
               begin(toBeFilled), GenerateSomething);

大量のデータを処理している場合、これは問題になる可能性があります(キャッシュに適さない)が、処理しているのと同じくらい小さいコンテナーでは、これはまったく問題になりません。

編集:もちろん、それを避けたい場合は、ファンクターを取るイオタを書くことができます(おそらく標準に含まれているはずです):

最初に、「numericx」と呼ぶ小さなヘッダーを作成します。

#ifndef NUMERICX_H_INC_
#define NUMERICX_H_INC_
namespace stdx { 
template <class FwdIter, class T, class Func>
void iota(FwdIter b, FwdIter e, T start_val, Func f) { 
    while (b != e)
        *b++ = f(start_val++);
}
}
#endif

[自明でないイテレータおよび/またはTの場合、別のステートメントでpost-incrementsをpre-incrementsに置き換える方がよい場合があることに注意してください]。

次に、それを使用する(今では些細な)コード:

#include "numericx"

stdx::iota(begin(toBeFilled), end(toBeFilled), 0, GenerateSomething);
于 2012-06-15T03:55:53.057 に答える
2
struct Filler {
    int real_;
    int &index_;
    Filler() : real_(0), index_(real_) {}

    int operator()() {
        return GenerateSomething(index_++);
    }
};

std::generate(ToBeFilled, ToBeFilled + 10, Filler());

マーク B のコメントにより編集されました。反復ごとに関数オブジェクトのコピーを作成するgenerate(私作成した)のバージョンでテストされました:

template <typename It, typename F>
void generate(It start, It finish, F func)
{
   for(;start != finish;++start)
   {
      F generator = func;
      *start = generator();
   }
}
于 2012-06-15T03:23:30.207 に答える