for std::generate, can passed function use index?

2019-08-01 21:37发布

问题:

A little hard to phrase in a question so I will use an example. Lets say I do:

generate(myvec.begin(), myvec.end(), func())

Can I have it so that func() can read the index that generate is up to such that:

int func()
{
   if(index<2)
       return 1;
   else
       return 2;
}

such that myvec[0]=1, myvec[1]=1, myvec[2]=2, myvec[3]=2,..., myvec[N]=2?

回答1:

Yes, if you use a function object as the generator (as juan points out, it is questionable whether this solution is guaranteed to work by the standard! Exercise caution and use Jerry's method.):

class mygenerator {
 public:
  mygenerator() : hits(0) {}

  int operator()() {
      hits++; 
      return (hits <= 2 ? 1 : 2);
  }

 private:
  int hits;
} 

...

mygenerator mg1;
std::generate(myvec.begin(), myvec.end(), mg1);


回答2:

The short answer is "no, not directly". It can create its own variable that should track with the index, but (in a case like this) there's simply no access to the index itself.

Under the circumstances, I'd almost certainly just use std::fill twice:

std::fill_n(myVec.begin(), 2, 1);
std::fill(myVec.begin()+2, myVec.end(), 2);

Shorter, and simpler.



回答3:

class funkygen 
{
  int index;

public:
  funkygen() 
    : index(0)
  { }

  int operator()() 
  { 
    if(t < 2)
      t++;

    return t; 
  }
};

/* other code */

funkygen f;

std::generate(myvec.begin(), myvec.end(), f);

As juanchopanza pointed out in a comment on another answer, the elements of vec are not guaranteed to be accessed in a particular sequential order. The only guarantee is that every item will be accessed exactly once.



标签: c++ vector