Most of the "ugly" of these examples only really matters for library authors and even then most of the time you'd be hard pressed to put yourself in these situations. Otherwise it "just works".
Basically any adherence to a modicum of best practices avoids the bulk of the warts that come with type deduction or at worst reduces them to a compile error.
For any seriously templated or metaprogrammed code nowadays a concept/requires is going to make it a lot more obvious what your code is actually doing and give you actually useful errors in the event someone is misusing your code.
There's nothing special about auto here. It deduces the same type as a template parameter, with the same collapsing rules.
decltype(auto) is a different beast and it's much more confusing. It means, more or less, "preserve the type of the expression, unless given a simple identifier, in which case use the type of the identifier."
That said, there are some contexts in which “auto” definitely improves the situation.
auto it = some_container.begin();
Not even once have I wished to know the actual type of the iterator.
For example:
auto a;
will always fail to compile not matter what flags.
int a;
is valid.
Also it prevents implicit type conversions, what you get as type on auto is the type you put at the right.
That's good.
CalChris•3h ago
plq•2h ago
https://news.ycombinator.com/item?id=11604474
Maxatar•2h ago
Type inference is usually reserved for more general algorithms that can inspect not only how a variable is initialized, but how the variable used, such as what functions it's passed into, etc...
zarzavat•1h ago
In a modern context, both would be called "type inference" because unidirectional type inference is quite a bit more common now than the bidirectional kind, given that many major languages adopted it.
If you want to specify constraint-based type inference then you can say global HM (e.g. Haskell), local HM (e.g. Rust), or just bidirectional type inference.
jb1991•25m ago