1

My question is for the C++ purists here. I know that Bjarne Stroustrop wants us to get in the habit of using C++ vectors: http://www.youtube.com/watch?v=YQs6IC-vgmo

For C-style arrays you do:

int arr[] = {69, 2, 3}; 

What is the equivalent way to initialize a C++ vector? That is, when you're programming in C++ and need a dynamic, random-access container and you already know some of the elements that need to be in it, what is the best way to initialize that sucker?

Obviously you can do

int myints[] = {16,2,77,29}; std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) ) 

but that's not very elegant ....

2
  • 3
    Are you OK with C++11? If yes, do std::vector<int> v = {1, 2, 3, 4}; :) Commented Jan 3, 2014 at 5:21
  • 2
    As of C++11, same as arrays. Else, create your own versions of std::begin and std::end. Commented Jan 3, 2014 at 5:21

2 Answers 2

5

C++11 syntax:

vector<int> arr = {69, 2, 3}; 

That's all.

The curly braces initalizer produces a std::initializer_list<int>, which is then passed to a std::vector constructor.

Sign up to request clarification or add additional context in comments.

3 Comments

@ Cheers and hth: Is this any better or worse? vector<int> arr{69,2,3};
@DavidO: Define "better", and there you have your answer. However, i prefer the =, where it's possible. I had to check whether arr{69, 2} produced a 2-item vector or invoking the repeat-constructor producing 69 items; happily it created a 2-item vector...
@DavidO It'd be required if the constructor in question was explicit. Otherwise it's a matter of preference.
2

If it's C++03 you're after, then use vector's iterating constructor (as you did); perhaps you can make it "look" more elegant by moving the array length into a header (macro).

// in some header template <typename T, size_t N> const char (&arr_len(const T (&arr) [N]))[N]; #define ARRAY_LEN(arr) sizeof(arr_len(arr)) // in your source int arr[] = { 1, 2, 3, 4 }; std::vector v(arr, arr + ARRAY_LEN(arr)); 

If it's C++11 like I posted in the comment, use the vector's initializer list taking constructor.

std::vector v{ 1, 2, 3, 4}; 

However, efficiency-wise I don't see why one would be better than the other.

11 Comments

@Koushik: Only if you're allowed to use C++11, the first part works in pure C++03. array_len returns the size of array at compile-time.
it would be nice with uppercase for the macro. worth noting that in C++03 (which it's meant for) it doesn't work for array of local type. however, we usually didn't mind. the nice thing about this approach is that it produces a compile time constant, which can be used to specify the size of another array.
@legends2k: because in C++03 templates couldn't be instantiated on local types. as i recall because they had no linkage. however, in c++11 still no linkage (as far as I'm aware), but template instantion allowed. i would have to look up the details to be sure of the reasons though.
while we're on it, the sizeof(a)/sizeof(*a) thing can also produce a compile time constant and be wrapped in a macro, but afaik only with run-time (dynamic) type checking... so it's mostly inferior. only relevant as an alternative for arrays of local types, in c++03.
@legends2k: oh. the problem is when a, inadvertently, is a pointer. the runtime checking can be done by dereferencing and taking address, use typeid to check if you still have the same type, put that in an assert(say) and put that again inside a comma expression. very awkward! but perhaps better than nothing.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.