I just read the chapter about this in Scott Meyers's latest book (
http://shop.oreilly.com/product/0636920033707.do ). Without reprinting the whole chapter here, he basically says there's these types of initialization statements in C++11:
1s) v2 a(1, 2); // requires you to write the constructor
2s) v2 b = v2(3, 4); // this is basically what Casey is doing, except with a standalone function rather than a constructor.
3s) v2 c{ 5, 6 };
4s) v2 d = { 7, 8 };
I suggested this one to Casey based on the way he was using his vector initialization function: v2 vec = v2{ 1, 2 }; Basically, replacing: v2 vec = V2( 1, 2); as closely as possible to his original syntax. However, I'd point out that neither approach, Casey's or my suggestion, are basic C++ initialization.
Casey's version uses a function to initialize a v2 structure based on the function arguments. The new v2 struct is returned from the function and assigned (copied) to the new vec being created. Because of several compiler implementation details, of which Casey is aware of and takes advantage of, his approach compiles down to the same machine code as any of the simple initialization syntaxes when building with optimizations enabled. Similar things would happen with the version I suggested. If you're a horrible nerd, you might be interested in these:
https://en.wikipedia.org/wiki/Return_value_optimization
https://en.wikipedia.org/wiki/Copy_elision
Back to Scott's initialization types:
v2 a(1, 2); I believe that Casey wanted to avoid using constructors in his code base, so this one is probably off the table, at least for his stream.
v2 b = V2(3, 4); Using the assignment operator is nice, but requires you to create a constructor or factory function.
v2 c{ 5, 6 }; What Scott calls "braced initialization". This C++11 style prevents two legacy C/C++ problems: C++'s "most vexing parse" (I doubt this often happens to Casey based on his programming style), and narrowing conversions (which, VS will generate a warning for using the previous two syntaxes, and maybe you don't care so much with simple vectors... I don't know). Anyway, this syntax works almost everywhere with few downsides. Personally, I would recommend this syntax for new C++ code, unless you are creating constructors that take std::initializer_list all over the place. If you don't know what std::initializer_list is and you're sticking mostly to what you see on Casey's stream it's not worth talking about here. Otherwise, if you're using the STL a bunch, there's more to know; I'd recommend you pick up Scott's book to learn the details.
v2 d = { 7, 8 }; This is basically the same as the previous option only with an additional assignment operator. It sort of seems like extra typing for no good reason, and doesn't quite work in as many places as the previous syntax. But, it's an option with C++11 compilers.
In reference to mmozeiko's comment: #3 and #4 will behave differently if you attempted to construct a new v2 with parameters that would cause a narrowing conversion. For example:
v2 b = V2(3.14f, 3.14f); // Compiles, no warnings.
v2 b = V2(3.14, 3.14); // Compiles, but causes VS to issue a warning.
v2 c{ 3.14f, 3.14f }; // Compiles, no warnings.
v2 c{ 3.14, 3.14 }; // Fails to compiles, error: narrowing conversion.
Braced initialization won't allow you to convert a double to a float without a cast.