
C++ 11 Auto: How to use and avoid abuse - ingve
http://www.acodersjourney.com/2016/02/c-11-auto/
======
albinofrenchy
I'd be more than annoyed if I saw someone name a function "xxInteger()"
because it returns an integer.

I don't actually think the first example was that bad, modulo some context.
Sometimes even knowing the type for this kind of thing isn't super important
to understand what the code is doing; ala opaque types.

~~~
takeawayandrun
What exactly is annoying?

I always want my variable names to be as long and descriptive as possible.
We're no longer in the teletype era and our monitors are huge. With
autocomplete there is no reason to keep variable names short

~~~
tomjen3
Thats the only acceptable way to write code, but it doesn't mean that names
can't be too expressive, for example I wouldn't accept nameing like this:

> RandomizeArrayPositionUsingFisherYatesShuffle

Since the algorithm detail is something I don't want to think about when I use
it and something that the implementer should be able to change without
changing the contract.

------
nercury
"auto a = ConjureMagic();" "SetMagic(a);"

The problem here is actually is an old one of failing to separate a getter
from a command.

It looks like ConjureMagic is causing side effects and modifying the state of
whatever class it belongs to.

This is also the reason one can't answer the question "what the heck is a?".
If the "ConjureMagic" is only a getter and does not modify class state, it may
probably need a better name, like "GetMaxMagicPossible". That renders an auto
no longer confusing, because this name explains more than the return type. If,
on the other hand this is just a command to conjure the magic and we are
getting the remaining amount only to immediately pass it to the member
"SetMagic" function, then there was no point in returning this value - it
could be done inside the "ConjureMagic" itself.

~~~
takeawayandrun
Having Getters for each member variable always seems fine and reasonable. It's
when you have getters that do "magic" that I feel a little.. unsure. Like if
it's taking a member and returning it in a different unit that seems kosher...
But there is a fuzzy line where at some point the Getter is doing too much
work to genuinely be a getter. It gives a false impression for the internal
structure of the program. But conveying the const'ness is important as you
describe (or semi-constness if you have caching)

~~~
zeta0134
I'm of the somewhat unpopular opinion that "getters for everything!" is a
philosophy that sounds good on paper, but results in writing a lot of getter
and setter functions and feeling safe, while ignoring these sorts of traps
cropping up everywhere.

Member variables are easy to reason about; they behave exactly like the type
they are, and in the case of built in types, have extremely consistent
behavior. Getters / setters are a black box of mystery; I like to reserve that
pattern for when there's going to be extra work to retrieve some value, so my
call site knows it needs to tip-toe around possible failures. While I can see
the value in using getters/setters for everything in something like an API or
framework, I don't see the value in trying to use them all the time, "just in
case."

------
danra
No.

In Herb Sutter's words, avoiding auto since it makes the code "unreadable":

 _...reflects a bias to code against implementations, not interfaces.
Overcommitting to explicit types makes code less generic and more
interdependent, and therefore more brittle and limited. It runs counter to the
excellent reasons to “write code against interfaces, not implementations”_

See [http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-
style-...](http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-
always-auto/)

~~~
p0nce
Why this dismissive comment? auto is definately overused in ways that are
unreadable, exactly like the blog author says. Marking the type explicitely
may be less generic in a way, but it helps readability so much by providing
redundancy.

~~~
ryanjshaw
The author only gives two problematic usage examples, the first of which
(ConjureMagic) nercury correctly addressed earlier as a symptom of poor OO
design (related to the 'code to implementations' quote above).

The second issue (async) is quite similar in my opinion, and in practice your
async handler will be explicitly decoupled and strongly typed at some point
for reasons of testability so the example is describing also an OO design
issue and not an issue with auto.

There may be real problems with auto but this article did not provide any
compelling evidence of them.

------
cheez
auto, the new range for and lambdas are my most used C++11 features. Also
make_shared/make_unique.

    
    
      auto ptr = make_shared<T>() 
    

Reads very nicely so I agree that if the type should be somewhere in the auto
expression. That is, use auto to remove redundancy. I just wish they would
have extended type deduction to lambda arguments so I could do:

    
    
      [](a,b){ ... }
    

Instead of:

    
    
      [](int a, int b) {...}
    

My understanding is that they're allowing:

    
    
      [](auto a, auto b) {...}
    

Bleh.

~~~
dbyte
auto with lambdas can be quite dangerous if you are adding different types
inside their bodies. Type promotion rules should be well understood. During
code reviews we spotted several overflow bugs when using ints because the dev
were thinking auto as a sort of very powerful resource.

Explicit casting if often required to make sure subtle bugs won't show up in
production.

~~~
cheez
What do you mean about promotion rules with auto?

------
ludamad
How much of these concerns could be alleviated by an IDE that makes the types
more visible?

~~~
millstone
That's what Herb Sutter argues in his Almost Always Auto post, but I would
disagree:

1\. The IDE cannot deduce the type within templates, and more code is moving
to templates (e.g. generic lambdas in C++14)

2\. Code is often read outside of IDEs: code review, search engines, etc.

3\. Should C++ become a language that requires an IDE to work effectively,
like Java? Probably not.

~~~
CyberDildonics
I would be very surprised if someone can meaningfully review C++ templates
without an IDE.

Really not reviewing a program inside an IDE is a poor idea in general.

~~~
dman
Some of us still use emacs and vim.

~~~
pjmlp
Yeah, some of us still listen to vinyl and tube radios.

~~~
dman
Unfortunately all the ides I tried make it non trivial to write extensions. I
program nearly 9 hours a day and using a tool that prevents automation of
common tasks is suboptimal.

~~~
pjmlp
On my case, they provide all the necessary automation features I care about.

~~~
dman
Out of curiosity which Language and IDE do you use?

~~~
pjmlp
Java, Scala, F#, C#, C++, JavaScript, SQL.

VS, Netbeans, Eclipse, Android Studio, SQL Developer.

------
alschwalm
Somewhat related, C++14 gets 'auto' for function return types, which really
makes me nervous (C++11 has a form of this, but not as powerful).The D
programming language uses 'auto' as the return type for many of the functions
in the standard library and this makes it, IMO, somewhat cumbersome to use.

In general, I don't think C++ (or D) devs should be using deduced return types
in the public interface, if at all possible.

------
fenesiistvan
So auto allows you to deal more easily with c++ crap, especially STL. My first
thing to do in all my c++ project is to import my in-house STL wrapper, which
makes STL usable for me. I never understood how people can work with raw STL.
I don't like at all working with templates and i am using it only in internal
class implementations. C++ without templates is so much more beautiful.

~~~
therein
Would you mind giving some examples? I don't find STL to be crap at all.

~~~
superrad
std::unordered_map<std::string, SomeClassName>::iterator it = hashmap.begin();

vs

auto it = hashmap.begin();

I find auto useful for cutting down some of the verbosity of templates STL
containers, but I can see how over use can lead to code requiring much more
referencing if maintaining code that rarely defines types.

~~~
therein
Oh no, I agree with that. I was specifically talking about fenesiistvan's
point about his STL wrapper. I was wondering what his use cases were.

No doubt auto is extremely useful in a case like the one you mentioned. In
fact, even more so in here:

for (std::unordered_map<std::string, std::unordered_map<std::string,
long>*>::const_iterator it = a.begin(); ...)

~~~
fenesiistvan
I am used with the old Delphi / C++ Builder style. I think that it is much
more clear than than bot the STL and the new trendy C11 style.

So my hashmap handling looks like this:

MHashMap _userlist = new MHashMap <HUser_>();

HUser *user = userlist->First();

while(user) { user->DoSomething(); user = userlist->Next(); }

------
DubiousPusher
I think one of the key things that makes 'auto' much more painful than 'var'
is that in Visual Studio, the intellisense in C# is much more reliable than
C++. Any ambiguous statement like the first example is quickly and resolved in
C# with a quick F12. In C++, this doesn't always work especially when you're
using any kind of cobbled together or hybrid build system.

A lot of times, the type is unimportant but when it is, this kind of usage can
bloat a simple task into 5 to 15 minutes of hunting through headers or
grepping.

It's strange to think of an IDE feature so impacting a language feature. The
stack is not supposed to affect in that direction but this is one case where
it really does.

------
davidshin
Will best practice for the auto keyword change when c++ concepts finally
arrive?

Of the 3 options below, the third seems best to me:

    
    
      SomeReallyLongTypeName* x = foo();  // old-school
    
      auto x = foo();  // c++11
    
      pointer x = foo();  // c++17 concepts

~~~
ambrop7
you can already do: auto *x = foo(); Which is actually more readable than
"pointer".

~~~
davidshin
Perhaps a better example be something like:

    
    
      smart_ptr<auto> x = foo();

------
cm2187
The unlikely return of VB's hungarian notation...

------
Dylan16807
The example at the start would be equally mildly confusing if it was written
as SetMagic(ConjureMagic());. The problem is not the auto. It's a normal case
of non-ideal function names.

------
irremediable
Unsure of the explicit typing one. Don't the Core Guidelines say to use it in
that case? The IDE's going to tell you the return type anyway.

