+ 1
What's different in two type of initilization in vector
Hi What's difference between vector<int> v {1,2,3} ; And vector<int> v = {1,2,3} ; Is it not different ? One is constructor and second is assignment or both are same ? Below code suggests same output... Am I missing some differences or both are same only ? https://code.sololearn.com/cAsLcMGc7D16/?ref=app
6 Answers
+ 3
In both cases, the constructor of std::vector is being called. This syntax is the list-initialization syntax, specifically, syntax (1) and (6) in this page
https://en.cppreference.com/w/cpp/language/list_initialization
If std::vector was an aggregate type, the above syntax would initialize its members directly. But since it isn't, the above syntax calls the constructor overload which takes an std::initializer_list, specifically constrcutor no. 10 here
https://en.cppreference.com/w/cpp/container/vector/vector
The copy constructor of `test` is being called since the constructor of std::vector copies the contents of the std::initializer_list that it recieves as argument in the constructor. (To avoid this, you should prefer using constructor (4) when you want to initialize vector with for default-constructed objects)
Refs:
Aggregate type:
https://en.cppreference.com/w/cpp/language/aggregate_initialization#Explanation
+ 3
[continued]
Rules of list-initialization: (bullet points 1 and 6 are useful in your case)
https://en.cppreference.com/w/cpp/language/list_initialization#Explanation
"Also for first case if I end up using round brackets , nothing happens I mean no constructor of class test gets called as below :
vector<test> v(test(),test(),test());"
This is weird. Since this is not list-initialization, all three `test()`s would be passed to the constructor of vector. This should technically be an error since I don't see any constructor which matches the arguments.
https://en.cppreference.com/w/cpp/container/vector/vector
I have suspicions that contructor (5) might be getting called. I say this because it is the only constructor that takes 3 arguments all which are of template types. But this should not be possible since `test` does not meet the requirements for Iterator and can also not be passed where type std::allocator is expected.
+ 2
I ran the code in clang with warnings, which made it clear what the problem is. This is warning from the compiler
```
file.cpp:28:19: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
{ vector<test> v(test(), test(), test()); }
^~~~~~~~~~~~~~~~~~~~~~~~
file.cpp:28:20: note: add a pair of parentheses to declare a variable
{ vector<test> v(test(), test(), test()); }
```
This is a typical case of Most Vexing Parse
https://stackoverflow.com/questions/14077608/what-is-the-purpose-of-the-most-vexing-parse
The compiler thinks that you are declaring a function. Changing '(' and ')' to '((' and '))' as the compiler suggests fixes the problem and results in an expected compiler error. This is a strong reason why you should prefer list-initialization in most places.
0
Seems ok...
Second might be constructor , but first is not an inilitalizer list constructor?
Also for first case if I end up using round brackets , nothing happens I mean no constructor of class test gets called as below :
vector<test> v(test(),test(),test());