有没有办法使用函数返回值使用std :: fill(),并且函数需要输入等于容器索引?

时间:2012-06-15 03:14:31

标签: c++ stl

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)。 通常我只需要一个特定的指针,所以我会像pObj->GetIt(0)一样使用它,但在某些情况下我需要得到所有这些,以便出现一个循环。

2 个答案:

答案 0 :(得分: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);

如果您正在使用大量数据,这可能会有问题(它相当缓存不友好),但是如果您使用的容器很小,这根本不是问题。

编辑:当然,如果你想避免这种情况,你可以写一个带有仿函数的iota(就像它们可能应该包含在标准中一样):

首先是一个小标题,我称之为“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,最好在单独的语句中使用预增量替换后增量]。

然后使用它的(现在琐碎的)代码:

#include "numericx"

stdx::iota(begin(toBeFilled), end(toBeFilled), 0, GenerateSomething);

答案 1 :(得分:2)

struct Filler {
    int real_;
    int &index_;
    Filler() : real_(0), index_(real_) {}

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

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

由于Mark B的评论而编辑。使用generate(由我编写)的版本进行测试,其中 为每次迭代制作一个函数对象的副本:

template <typename It, typename F>
void generate(It start, It finish, F func)
{
   for(;start != finish;++start)
   {
      F generator = func;
      *start = generator();
   }
}