Quickly way to push_back 1 to n to std::vector

I want to push back 1 to n numbers to a single int vector. Could that be done in one line without loop?

1
2
3
  std::vector vector(n);
  // To transform in one line without loop
  for (uint32_t i = 0; i < n; ++i) vector.push_back(i);
Last edited on
The only way to combine initializing a vector and putting elements from 1 to n would be by using one of the constructors of vector.


(1) empty container constructor (default constructor)
    Constructs an empty container, with no elements.
(2) fill constructor
    Constructs a container with n elements. Each element is a copy of val (if provided).
(3) range constructor
    Constructs a container with as many elements as the range [first,last), with each element emplace-constructed from its corresponding element in that range, in the same order.
(4) copy constructor (and copying with allocator)
    Constructs a container with a copy of each of the elements in x, in the same order.
(5) move constructor (and moving with allocator)
    Constructs a container that acquires the elements of x.
    If alloc is specified and is different from x's allocator, the elements are moved. Otherwise, no elements are constructed (their ownership is directly transferred).
    x is left in an unspecified but valid state.
(6) initializer list constructor
    Constructs a container with a copy of each of the elements in il, in the same order. 

http://www.cplusplus.com/reference/vector/vector/vector/

As you can see, what you're asking is not supported by any constructor.
The closest you can get in one line is with: vector <int> vec({ 1, 2, 3, 4, .., n });

Everything else requires at least two lines. But CakeTheOcean, I understand that you want to compress code as you did with your other post, maybe because it looks more neat, but understand that it only makes it harder for other people to read and understand.

The two lines you wrote is perfect. Can't get anything better than that!
Oh and by the way I just realized that your snippet is wrong.
1
2
3
  std::vector vector(n);
  // To transform in one line without loop
  for (uint32_t i; i < n; ++i) vector.push_back(i);


Firstly you forgot to initialize i (okay innocent mistake) and you didn't give your vector a type. But the vector, if you run it, would have n number of '0' elements followed by whatever you pushed back to the vector. So that's wrong.

Simple fix would be to remove (n). Or instead of push_back(), use indexes, which I think is a better idea.

lastchancie wrote:
http://www.cplusplus.com/reference/numeric/iota/

But it's the same as for (uint32_t i=1; i <= n; ++i) vector[i-1] = i;?

By the way OP, if you must have the one line then you can do this:
vector <int> vec(n), iota (vec.being(), vec.end(), 1);
(yes using comma operator to cheat.)

Or you could use for-loop like you initially intended instead of iota.
Last edited on
I'm sorry if I'm wrong.. But TheIdeasMan,
void generate (ForwardIterator first, ForwardIterator last, Generator gen);

Since the arguments are iterators (i.e point to the vector), you cannot still merge the initializing and filling into one line.. right?
Grime wrote:
Since the arguments are iterators (i.e point to the vector), you cannot still merge the initializing and filling into one line.. right?


That wasn't the question.
Yes it was the question. OP wants to combine the two lines he posted into one line. Which is initializing and filling.

Wait.. what did you think? *confused*

edit: Okay maybe it was because OP said "without loop" but in that perspective both functions loop through the vector anyway so there's no reason to use them over the loop since all of them basically do the same thing.
Last edited on
@Grime

Do you know the difference between a declaration and initializing? I thought you did, seen as you have already read and understood everything on the internet.
Why so harsh? And realize that std::vector vector(n); is initializing and not just declaring. ;)

And TheIdeasMan, what do you mean by
seen as you have already read and understood everything on the internet.

Why do you say that? Is it a reference to another post? When have I said that I've read and understood everything from the internet?

For some reason I think that you're mad with me (otherwise you wouldn't have added that extra comment) but I don't know why.
Last edited on
1
2
// https://www.boost.org/doc/libs/1_69_0/libs/iterator/doc/counting_iterator.html
const std::vector<int> vec( boost::counting_iterator<int>(1),  boost::counting_iterator<int>(n+1) ) ;

http://coliru.stacked-crooked.com/a/d3ea885336e7520d
There's nothing JLBorges can't do.. ;o
Damn man how are you so awesome.. Is there anything in C++ that you don't know!

And also you're really helpful. ;)
A rose by any other name would smell as sweet

Or put in other words: if the loop has foul stench, then every feasible way to set values to a vector does too.

std::iota is implemented with a loop.
std::vector's range constuctor is implemented with a loop.
Recursive solution would be effectively iteration too.

The question is thus: If it does not look like a duck, is it still a duck?
if this is really what you wanted, my answer is 'don't store it'.
any time you use that vector, you are going to do either a loop already or have some index, eg data*vec[i] or whatever you plan to DO with it. This is silly, as i is correlated to vec[i] directly. just say data*(i) instead and save the memory and pointer access and other slowness injected by the vector.


you can't always do that, so your question has merits for less simple examples, but ANY time your index and your vector have a simple and tight correlation like this, just skip storing the vector at all.
In C++20 flavour, using ranges::v3:

std::vector v{ranges::view::closed_indices(0, 10)};
Last edited on
Grime wrote:
By the way OP, if you must have the one line then you can do this:
vector <int> vec(n), iota (vec.being(), vec.end(), 1);
(yes using comma operator to cheat.)

This declares two vectors, vec and iota, but fails because there is no vector constructor that takes two iterators and an integer as argument.
You're right Peter i didn't realise iota would be considered as vector decoration.
Last edited on
Topic archived. No new replies allowed.