o_luka02
o_luka02

Reputation: 3

Is it possible to use std::generate on an empty std::vector for which we have only called .reserve?

My main function:


#include <vector>
//#include <algorithm>
#include <iostream>

int main()
{

    std::vector<char> v;
    int len = 2 * 5 + 1;
    v.reserve(len);

    // using for loop and push_back

    for (int i = 0; i < len; i++)
        (i % 2) ? v.push_back(' ') : v.push_back('|');

    // using generate

    // std::generate(v.begin(), v.end(), [n = 0]() mutable { return (n++ % 2) ? ' ' : '|'; });
    // std::generate_n(v.begin(), len, [n = 0]() mutable { return (n++ % 2) ? ' ' : '|'; });

    for (const char& c : v)
        std::cout << c;

    return 0;
}

Using for loop and push_back I get the output:

| | | | | |

Using std::generate has no effect, and using std::generate_n results in a failed assertion:

Expression: cannot seek vector iterator after end

As I understand it, calling .reserve doesn't change the "distance" between iterators begin and end, so I can't pass them to std::generate in order to place ' ' and '|' in the memory I reserved for v. I would have to increase v.end by len (len+1?), is that even possible? Or is there another way to make this work, without using .push_back or similar operations, or without initializing reserved memory with something then overwriting it? Also not sure if the lambda is correct, but that's not important.

Upvotes: 0

Views: 143

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275820

You can use std::generate_n with a std::back_inserter on the container.

This will resize the container as it generates.

The reserve is optional, but it will save on container resizes and reallocations possibly.

Upvotes: 4

Related Questions