Question: What is the actual benefit and purpose of `initializer_list`, for unknown number of parameters? Why not just use `vector` and be done with it?

In fact, it sounds like just a `vector` with another name. Why bother?

The only "benefit" I see of `initializer_list` is that it has `const` elements, but that doesn't seem to be a reason enough to invent this whole new type. (You can just use a `const vector` after all.)

So, what am I mising?

Answer: 
It is a sort of contract between the programmer and the compiler. The programmer says `{1,2,3,4}`, and the compiler creates an object of type `initializer_list<int>` out of it, containing the same sequence of elements in it. This contract is a requirement imposed by the language specification on the compiler implementation.

That means, it is not the programmer who creates manually such an object but it is the compiler which creates the object, and pass that object to function which takes `initializer_list<int>` as argument. 

The `std::vector` implementation takes advantage of this contract, and therefore it defines a constructor which takes `initializer_list<T>` as argument, so that it could initialize itself with the elements in the initializer-list.

Now **suppose for a while** that the `std::vector` doesn't have any constructor that takes `std::initializer_list<T>` as argument, then you would get this:

```
 void f(std::initializer_list<int> const &items);
 void g(std::vector<int> const &items);

 f({1,2,3,4}); //okay
 g({1,2,3,4}); //error (as per the assumption)

```

As per the assumption, since `std::vector` doesn't have constructor that takes `std::initializer_list<T>` as argument, which *implies* you cannot pass `{1,2,3,4}` as argument to `g()` as shown above, because the compiler *cannot* create an instance of `std::vector` out of the expression `{1,2,3,4}` **directly**. It is because no such contract is ever made between programmer and the compiler, and imposed by the language. It is *through* `std::initializer_list`, the `std::vector` is able to create itself out of expression `{1,2,3,4}`. 

Now you will understand that `std::initializer_list` can be used wherever you need an expression of the form of `{value1, value2, ...., valueN}`. It is why other containers from the Standard library also define constructor that takes `std::initializer_list` as argument. In this way, no container depends on any other container for construction from expressions of the form of `{value1, value2, ...., valueN}`.

Hope that helps.
Well, `std::vector` *has* to use `initializer_list` to get that syntax as it obviously can't use itself.

Anyway, `initializer_list` is intended to be extremely lightweight. It can use an optimal storage location and prevent unnecessary copies. With `vector`, you're always going to get a heap allocation and have a good chance of getting more copies/moves than you want.

Also, the syntax has obvious differences. One such thing is template type deduction:

```
struct foo {
    template<typename T>  
    foo(std::initializer_list<T>) {}
};

foo x{1,2,3}; // works

```

`vector` wouldn't work here.