4 ms·
There are two different features interfering, which were added at the same time. The {42,1} is an "initializer list", which was a way of passing a list of thin
by CJefferson 5y ago
There are two different features interfering, which were added at the same time.
The {42,1} is an "initializer list", which was a way of passing a list of things to a constructor.
However, at the same time, something called "uniformed initalization" was added, which used {}, to "clean up" how constructors work.
However, from looking at a piece of code it's impossible to know if it is trying to call "initializer list" or "uniformed inialization". The "initalizer list" wins in this case, when the items are all things you can put in the vector.
- pierrebai 5y agoOh how I agree about the uniform initialization! And to make matter worse, I now work on a code base where it is the mandated form in the coding standard. At least your initial example now gives me ammunition against it, but too late for this coding standard. It makes code look silly, too, as now initialization looks different from assignment. int i { a + 2 }; i = a + 4; int j = a + 2; j = a + 4; // ah! consistency!
- ncmncm 5y agoIt is good for initialization to look different. It is different. Not so much so for int, but maybe hugely different for other types.
- pjmlp 5y agoTo build up on sibling's answer that isn't the same thing. The first one will call the initialization constructor, whereas the second form will initialize the object and then apply one form of copy construction, depending on which ones are available (user provided or compiler generated). It just happens that for int that doesn't matter in practice.
- tialaramex 5y agoAlso, although this might be more obvious to people familiar with any C-like language, C++ considers that since 'x' is a character, and its characters are fundamentally just an integer type (maybe a signed 8-bit integer, it depends) the third list is just two constant integers, which are a perfectly reasonable thing to put in a list. Even though that's obviously not what a human sees. In a language that isn't just pretending to be strongly typed, the compiler would notice that char and whatever-integer-type-42-is aren't the same type, and it would reject your program as nonsense. But that confusion gets much less chance if the language explicitly distinguishes initialising collections so that "I want N of X" is different from "I want N, and X". Compare Rust's vec! macro: let mut v = vec!['x'; 42]; // NOTE semi-colon. Compiles, vector of 42 x characters let mut v = vec!['x', 42]; // NOTE comma. Does not compile let mut v = vec![b'x', 42]; // NOTE comma. Compiles, vector containing 120 (the ASCII code for 'x') and 42 as bytes let mut v = vec![b'x'; 420]; // NOTE semi-colon. Compiles, vector of 420 bytes with value 120 let mut v = vec![b'x', 420]; // NOTE comma. Does not compile unless you explicitly tell Rust that you mean the low 8-bits of 420 if you do this I'd actually be enthusiastic about a Clippy warning for the middle one, because it feels like the odds are better than they should be that wasn't what you meant. But on the other hand, the odds of you wanting either possibility are slim, so, not a priority.
- still_grokking 5y agoRust is one of the greatest new mainstream languages. But what they do with semicolons is pure brain damage. Having different complex semantics encoded purely in semicolons is nuts imho. I don't get how someone could create such mess in an otherwise mostly quite sane language. Especially as semicolons are an archaic artifact that shouldn't be used for mostly anything in a modern language, imho, as it's just useless noise (besides when writing some well readable one-liners of course ;-)).