6

The iota template function was added to the standard library to fill an iterator range with an increasing sequence of values.

  template<typename ForwardIterator, typename Tp>
    void
    iota(ForwardIterator first, ForwardIterator last, Tp value)
    {
      for (; first != last; ++first)
        {
          *first = value;
          ++value;
        }
    }

Most other templates in <numeric> have versions that accept user-specified operators. Having this:

  template<typename ForwardIterator, typename Tp, typename Operator>
    void
    iota(ForwardIterator first, ForwardIterator last, Tp value, Operator op)
    {
      for (; first != last; ++first)
        {
          *first = value;
          op(value);
        }
    }

would be convenient if you don't want to (or can't) overload operator++() for Tp. I would find this version more widely usable than the default operator++() version. <

Xeo
  • 129,499
  • 52
  • 291
  • 397
emsr
  • 15,539
  • 6
  • 49
  • 62
  • You're right, with lambdas the second version is not only more flexible than the first, but almost as easy to use for increment. – Ben Voigt Jul 08 '11 at 02:31

2 Answers2

5

I suspect the reason is the usual mix of one or more of the following reasons:

  • No one submitted a proposal
  • It wasn't considered important enough for this version (which was already huge, and very late)
  • it fell through the cracks and was forgotten (like copy_if in C++98)
  • it is easy to replace using std::generate.
jalf
  • 243,077
  • 51
  • 345
  • 550
4

With lambdas, the second version doesn't save much, you can just use std::generate.

template<typename ForwardIterator, typename Tp, typename Operator>
void iota(ForwardIterator first, ForwardIterator last, Tp value, Operator op)
{
  std::generate(first, last, [&value,&op](){auto v = value; op(value); return v;});
}

In fact, this makes the existing implementation of std::iota very redundant:

template<typename ForwardIterator, typename Tp>
void iota(ForwardIterator first, ForwardIterator last, Tp value)
{
  std::generate(first, last, [&value](){return value++;});
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • True, iota probably just blesses the SGI version which is distributed by gcc as an extension and probably other implementations. – emsr Jul 08 '11 at 02:52
  • 1
    `partial_sum` is even better (no `[&]`). `vector i(10,0); partial_sum(i.begin(),i.end(),i.begin(),[](int p, int c) {return p++;}` – kirill_igum Jan 25 '13 at 00:37
  • @kirill: Nearly so. But `partial_sum` doesn't accept a `value` parameter to seed the accumulation. Also the `++` postincrement in your code snippet is useless... the updated value of `p` is discarded immediately. In fact, your code snippet is totally wrong, and doesn't create an increasing sequence at all. – Ben Voigt Jan 25 '13 at 01:09
  • @BenVoigt @kirill_igum thanks, it should be `++p`. now it works. you can also modify the lambda function or have [&value]. the main point is that's another way. you can use it if you want something quick and don't want to make another function. – kirill_igum Jan 25 '13 at 01:46
  • @kirill: It should be `p+1`. But `std::generate` works quite well already, and gives the flexibility in starting value that `partial_sum` doesn't. – Ben Voigt Jan 25 '13 at 01:56