A few comments on the language features.
Almost always auto? Or are there cases when auto is not desired?
Do we use generic lambdas (C++14)? Or C++11 non-generic lambdas?
I think using auto almost everywhere is good. There are however places where we should refrain from using this feature, mainly for readability and sanity purposes. It's really great to replace lengthy types (e.g. iterators) or when we don't actually care about the type itself. But we should probably manually write the type we want to use if several types could be possible depending only on some subtle factors (I'm thinking about all the arithmetic types here) or if we want to avoid unintended type conversions.
C++14 generic lambda are here for a reason too: when the type of the arguments are obvious, `auto` is perfectly adapted.
In other words, I believe type inference should be used whenever possible but we should clearly tag variable with an explicit type when some confusing type deduction rules happen. I encourage people to read this SO answer:
http://stackoverflow.com/a/15726504/520217Do we rather specify the lambda return type or static_cast a return value that causes ambiguity?
Lambda should be used for simple functions, so if the return type is too complex or non-obvious in the context of the lambda, it should probably be a a function instead. With that in mind, the return type should be omitted most of the time and preferred over static_cast in my opinion.
Uniform initialization? {} everywhere or () as it was in C++03?
Using `{}` to init var is better than using `()` to trigger errors instead of weak warning when some unintended conversion occurs. However, when calling the ctor of an object with multiple arguments, we should probably use `()` when there is one overload (that we don't want to use) of the constructor taking an `std::initializer_list` to avoid potential confusion.
I assume we make use of override everywhere where it makes sense?
and `final`. :-)
When do we make use of strongly typed enumerations? Everywhere? Or are there exceptions?
I guess there could be some exceptions, but usually I'd go for strongly types enum.
Rule of Zero everywhere possible and Rule of Five elsewhere? (I am actually a firm believer of this.)
The rule of five has the advantage to make things clear and documented, so I'd vote for this one.
As for C++17, there are some nice features:
- `std::optional` is a nice library addition -- not sure how we can leverage this however,
- nested namespace declaration would be nice to have, but in itself cannot justify to use this standard,
- attribute for enumerators would be interesting in the future to mark some as deprecated but for v3.0 this should not be required,
- improvements on if (constexpr + if(init; cond)) could be nice to have for readability purposes,
- structure binding would be nice for Vector2/3 (API-wise) -- considering this as a conditionally supported would be good IMO.