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 ....

legends2k
  • 31,634
  • 25
  • 118
  • 222
user2967799
  • 221
  • 7
  • 12

2 Answers2

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.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • @ Cheers and hth: Is this any better or worse? `vector arr{69,2,3};` – DavidO Jan 03 '14 at 05:28
  • @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... – Cheers and hth. - Alf Jan 03 '14 at 05:33
  • 1
    @DavidO It'd be required if the constructor in question was `explicit`. Otherwise it's a matter of preference. – Praetorian Jan 03 '14 at 05:34
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.

legends2k
  • 31,634
  • 25
  • 118
  • 222
  • @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. – legends2k Jan 03 '14 at 05:40
  • 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. – Cheers and hth. - Alf Jan 03 '14 at 05:41
  • @Cheersandhth.-Alf: Made the macro uppercase. Why _it doesn't work for array of local type_? – legends2k Jan 03 '14 at 05:45
  • 2
    @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. – Cheers and hth. - Alf Jan 03 '14 at 05:47
  • Got it, thanks! Adding [the relevant post](http://stackoverflow.com/q/742607/183120) for others. – legends2k Jan 03 '14 at 05:48
  • 1
    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. – Cheers and hth. - Alf Jan 03 '14 at 05:50
  • But isn't `sizeof` evaluated at compile-time (except for C's VLAs)? – legends2k Jan 03 '14 at 05:52
  • @legends2k: not sure what you mean. in c++ `sizeof` is very much compile time. in C its broken for VLAs by not being compile time for them. that will not be repeated for VLAs in C++14. if they eppear in C++14. – Cheers and hth. - Alf Jan 03 '14 at 05:53
  • I was asking regarding the `sizeof` solution to get the array size, where you'd mentioned it'll work only with run-time type checking. – legends2k Jan 03 '14 at 05:54
  • 1
    @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. – Cheers and hth. - Alf Jan 03 '14 at 05:57
  • @Cheersandhth.-Alf VLA's are coming to c++14? is it that std::dynarray thingy or c-like VLA? – Koushik Shetty Jan 03 '14 at 06:00