217

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.

3
  • 3
    There's also how-to initialize 'const std::vector<T>' like a c array. Commented Jan 18, 2012 at 7: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) Commented Apr 25, 2013 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 Commented Jun 6, 2013 at 23:33

2 Answers 2

291

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)); 
Sign up to request clarification or add additional context in comments.

14 Comments

Or simply: std::vector<int> v(vv, vv+2);
Or more robustly: std::vector<int> 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.
I know this is an old question, but what exactly are you doing here: std::vector<int> 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: en.cppreference.com/w/cpp/container/vector/vector without supplying the third argument, which defaults to Allocator(). I know I'm missing something.
I think std::vector<int> 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.
@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.
|
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; 

2 Comments

Is it possible to move data_ to v instead of calling the copy constructor?
Hello Per! I suppose you do like this (warning, untested): operator std::vector<T>&& () { return std::move(data_); }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.