215

I want to initialize a vector like we do in case of an array.

Example

int vv[2] = {12, 43};

But when I do it like this,

vector<int> v(2) = {34, 23};

OR

vector<int> v(2);
v = {0, 9};

it gives an error:

expected primary-expression before ‘{’ token

AND

error: expected ‘,’ or ‘;’ before ‘=’ token

respectively.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Md Faisal
  • 2,931
  • 8
  • 29
  • 34
  • 3
    There's also [how-to initialize 'const std::vector' like a c array](http://stackoverflow.com/questions/231491/how-to-initialize-const-stdvectort-like-a-c-array/254143). – Shadow2531 Jan 18 '12 at 07:29
  • You should enable C++11 support in your compiler, e.g. `g++ -std=c++11 your_file.cc`. Then you can use initializer list constructor of the thread (the last item in [this reference](http://en.cppreference.com/w/cpp/container/vector/vector)) –  Apr 25 '13 at 11:51
  • 1
    Not a dupe - the other question is how to do it with old c++, WTF's answer is how to do it now – Martin Beckett Jun 06 '13 at 23:33

2 Answers2

290

With the new C++ standard (may need special flags to be enabled on your compiler) you can simply do:

std::vector<int> v { 34,23 };
// or
// std::vector<int> v = { 34,23 };

Or even:

std::vector<int> v(2);
v = { 34,23 };

On compilers that don't support this feature (initializer lists) yet you can emulate this with an array:

int vv[2] = { 12,43 };
std::vector<int> v(&vv[0], &vv[0]+2);

Or, for the case of assignment to an existing vector:

int vv[2] = { 12,43 };
v.assign(&vv[0], &vv[0]+2);

Like James Kanze suggested, it's more robust to have functions that give you the beginning and end of an array:

template <typename T, size_t N>
T* begin(T(&arr)[N]) { return &arr[0]; }
template <typename T, size_t N>
T* end(T(&arr)[N]) { return &arr[0]+N; }

And then you can do this without having to repeat the size all over:

int vv[] = { 12,43 };
std::vector<int> v(begin(vv), end(vv));
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 23
    Or simply: std::vector v(vv, vv+2); – Violet Giraffe Jan 18 '12 at 07:25
  • 12
    Or more robustly: `std::vector v(begin(w), end(w);`. The `begin` and `end` are standard in C++11 (but then you don't need them), but should be in your tool kit otherwise. – James Kanze Jan 18 '12 at 09:22
  • 2
    I know this is an old question, but what exactly are you doing here: `std::vector v(&vv[0], &vv[0]+2);` ? What I see is, you're constructing a vector with room for `&vv[0]` (which will be a memory address) values, and filling each space in the vector with `&vv[0]+2`... That would be using constructor 2 on this page: http://en.cppreference.com/w/cpp/container/vector/vector without supplying the third argument, which defaults to Allocator(). I know I'm missing something. – Mortimer McMire Jun 22 '13 at 19:45
  • 2
    I think `std::vector v(&vv[0], &vv[0]+2)` is invoking the 4th constructor on that page, actually. The constructor can take the first and last element in a range and create a vector with everything in between. The tipoff is the `&` will result in memory addresses. – Prashant Kumar Jun 23 '13 at 13:43
  • What if I want to initialize an array on the heap? – qed Jul 16 '14 at 18:48
  • @qed what do you think `vector` is? – R. Martinho Fernandes Jul 16 '14 at 20:12
  • I don't know, a data container? – qed Jul 16 '14 at 20:51
  • And what's an array if not a data container, too? – R. Martinho Fernandes Jul 16 '14 at 21:37
  • @qed A vector *is* an array on the heap. – R. Martinho Fernandes Jul 16 '14 at 23:36
  • @R.MartinhoFernandes Cool. But how come we never delete a vector by hand? – qed Jul 17 '14 at 14:00
  • @R.MartinhoFernandes And if I do `vector b {1, 2}`, is `b` then a pointer to a vector on the heap? Is that different from `vector* b = new vector; b.push_back(1); b.push_back(2)`? – qed Jul 18 '14 at 10:59
  • 1
    @qed We never delete vectors by hand because they have a destructor that automatically deletes the stuff on the heap, and the destructor is automatically called when the vector goes out of scope. – Buge Aug 04 '14 at 15:28
  • @qed Your second example has a bug. I think you mean `b->push_back(1);`. In the first example b is not a pointer, it is a object. The difference between those two examples is where the metadata (size and address of the main data) is stored. In the first example the size and address of the main data are stored on the stack. In the second example the size and address of the main data are stored on the heap. In both cases the main data itself is stored on the heap. – Buge Aug 04 '14 at 15:30
  • Which standard do you mean by `new` – Tik0 Jul 21 '17 at 02:44
32

You can also do like this:

template <typename T>
class make_vector {
public:
  typedef make_vector<T> my_type;
  my_type& operator<< (const T& val) {
    data_.push_back(val);
    return *this;
  }
  operator std::vector<T>() const {
    return data_;
  }
private:
  std::vector<T> data_;
};

And use it like this:

std::vector<int> v = make_vector<int>() << 1 << 2 << 3;
Viktor Sehr
  • 12,825
  • 5
  • 58
  • 90
  • 2
    Is it possible to move *data_* to *v* instead of calling the copy constructor? – Per Feb 21 '18 at 14:19
  • 2
    Hello Per! I suppose you do like this (warning, untested): operator std::vector&& () { return std::move(data_); } – Viktor Sehr Feb 22 '18 at 00:22