Comment by locknitpicker
3 days ago
> Template resolution solved that in the past, but C++ today allows auto in so many places that I'm uncertain that it can be done without some flow based support (if constexpr comes to mind).
This concern is unfounded. The auto keyword in C++ acts as mere syntactic sugar. It works only when the compiler is able to tell exactly what's the type by evaluating the expression.
The auto keyword is also considered a code smell for the same reason: just because the compiler can tell exactly what the type is expected to be, that does not mean the developer can. Therefore it makes the code harder to reason about.
> The auto keyword is also considered a code smell for the same reason: just because the compiler can tell exactly what the type is expected to be, that does not mean the developer can. Therefore it makes the code harder to reason about.
This really depends though. In many cases even the programmer can tell the type of auto because its on the very same line and not using auto would mean needlessly repeating it.
In other cases (e.g. iterators) the programmer also doesn't need to care about the concrete type.
GP was possibly arguing against Herb Sutter's "almost always auto". C++ wasn't designed for auto and it shows. You can't rely on it always doing the right thing or at least a safe thing in C++, unlike in Rust - I've seen bugs due to auto. It is also often helpful to spell out the concrete type in important places such as (most/many) variable definitions.
I'm also fine with auto if it just repeats information, especially so if the concrete type takes half of your line length budget (yes it's an iterator over that container containing...).
Yeah, when auto first came out a few people started abusing it everywhere making for unreadable code. Most developers settled quickly on much better rules for using auto that do not destroy readability, and never abused it in the first place. Auto is intended for and works very well to avoid typing very long types where you often never care.
Iterators is the common example: the type name is always long, and nearly always used in a context where it is obvious. Even if you do care about the type, looking up the iterator is wrong - you always first look up the base type (ie std:vector) first to understand the iterator, only rarely do you need to dig into the iterator once you understand the base type.
Generic code (template and non-template) are the other - they type could be anything, so trying to specify more detail isn't going to gain you anything.