Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is it appropriate to use 'auto' in C++? [duplicate]

I've been using the new auto keyword available in the C++11 standard for complicated templated types which is what I believe it was designed for. But I'm also using it for things like:

auto foo = std::make_shared<Foo>();

And more skeptically for:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

I haven't seen much discussion on this topic. It seems that auto could be overused since a type is often a form of documentation and sanity checks. Where do you draw the line in using auto and what are the recommended use cases for this new feature?

To clarify: I'm not asking for a philosophical opinion; I'm asking for the intended use of this keyword by the standard committee, possibly with comments on how that intended use is realized in practice.

like image 480
Alan Turing Avatar asked Jun 22 '11 04:06

Alan Turing


People also ask

When should I use Auto?

The auto keyword is a simple way to declare a variable that has a complicated type. For example, you can use auto to declare a variable where the initialization expression involves templates, pointers to functions, or pointers to members.

What is the use of auto in C?

auto: This is the default storage class for all the variables declared inside a function or a block. Hence, the keyword auto is rarely used while writing programs in C language. Auto variables can be only accessed within the block/function they have been declared and not outside them (which defines their scope).

When should you make use of Auto in C++?

In C++11, auto can be used for declaring local variables and for the return type of a function with a trailing return type. In C++14, auto can be used for the return type of a function without specifying a trailing type and for parameter declarations in lambda expressions.

Should I always use Auto in C++?

Use auto everywhere you can—particularly const auto so that side effects are less of a concern. You won't have to worry about types except in the obvious cases, but they'll still be statically verified for you, and you can avoid some repetition.


3 Answers

I think that one should use the auto keyword whenever it's hard to say how to write the type at first sight, but the type of the right hand side of an expression is obvious. For example, using:

my_multi_type::nth_index<2>::type::key_type::composite_key_type::
    key_extractor_tuple::tail_type::head_type::result_type

to get the composite key type in boost::multi_index, even though you know that it is int. You can't just write int because it could be changed in the future. I would write auto in this case.

So if the auto keyword improves readability in a particular case then use it. You can write auto when it is obvious to the reader what type auto represents.

Here are some examples:

auto foo = std::make_shared<Foo>();   // obvious
auto foo = bla();                     // unclear. don't know which type `foo` has

const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
                                      // since max_size is unsigned

std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
                                      // ok, since I know that `it` has an iterator type
                                      // (don't really care which one in this context)
like image 98
Kirill V. Lyadvinsky Avatar answered Oct 21 '22 17:10

Kirill V. Lyadvinsky


Easy. Use it when you don't care what the type is. For example

for (const auto & i : some_container) {
   ...

All I care about here is that i is whatever's in the container.

It's a bit like typedefs.

typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;

Here, I don't care whether h and w are floats or doubles, only that they are whatever type is suitable to express heights and weights.

Or consider

for (auto i = some_container .begin (); ...

Here all I care about is that it's a suitable iterator, supporting operator++(), it's kind of like duck typing in this respect.

Also the type of lambdas can't be spelled, so auto f = []... is good style. The alternative is casting to std::function but that comes with overhead.

I can't really conceive of an "abuse" of auto. The closest I can imagine is depriving yourself of an explicit conversion to some significant type -- but you wouldn't use auto for that, you'd construct an object of the desired type.

If you can remove some redundancy in your code without introducing side effects, then it must be good to do so.

Counterexamples (borrowed from someone else's answers):

auto i = SomeClass();
for (auto x = make_unsigned (y); ...)

Here we DO care what the type is, so we should write Someclass i; and for(unsigned x = y;...

like image 30
spraff Avatar answered Oct 21 '22 16:10

spraff


Use auto everywhere you can—particularly const auto so that side effects are less of a concern. You won’t have to worry about types except in the obvious cases, but they’ll still be statically verified for you, and you can avoid some repetition. Where auto isn't feasible, you can use decltype to express types semantically as contracts based on expressions. Your code will look different, but it will be a positive change.

like image 26
Jon Purdy Avatar answered Oct 21 '22 17:10

Jon Purdy