Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

What are the pros/cons to using the auto keyword, especially in for loops?

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->something();
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->second->something();
}

for(auto it = x.begin(); it != x.end(); i++)
{
   it->??
}

Seems like if you don't know whether you have an iterator for a map or a vector you wouldn't know whether to use first or second or just directly access properties of the object, no?

This reminds me of the C# debate on whether to use the keyword var. The impression I'm getting so far is that in the C++ world people are ready to adopt the auto keyword with less of a fight than var in the C# world. For me my first instinct is that I like to know the type of the variable so I can know what operations I can expect to perform on it.

share|improve this question
2  
Wait! There was a fight about whether to use var? I missed that. –  pdr May 12 '12 at 5:19
7  
Even better, you can just use for (auto& it : x) (or without reference if you want copying) –  Tamás Szelei May 12 '12 at 7:46
3  
Seems to me if you're writing a loop to iterate over the contents of x and you don't even know what x is, you shouldn't write that loop in the first place ;-) –  nikie May 13 '12 at 9:10
    
@fish: range based for-loops rules, but I would have been pedantic and done: 'for (T& it : x)' instead when using range based for-loops, as I feel using auto there is less informative. Kind of a misuse of auto in my mind. –  martiert Jan 3 '13 at 13:41
add comment

5 Answers

In your example:

for(auto it = x.begin(); it != x.end(); i++)
{
  it->??
}

there has to be a declaration for x visible. Therefore the type of it should be obvious. If the type of x isn't obvious, then the method is too long, or the class is too large.

share|improve this answer
3  
Also, x is a very bad variable name for a container. In some situations you can most likely just look at the (semantically valuable) name and infer the possible operations. –  Max May 11 '12 at 23:39
    
@Max: only used x as an generic example, I tend to use quite descriptive variable names. –  User May 12 '12 at 0:05
    
@User Of course, I didn't assume that was a real-world example ;) –  Max May 12 '12 at 0:28
add comment

The motivations in C++ are more extreme, as types can become vastly more convoluted and complex than C# types due to metaprogramming and other things. auto is faster to write and read and more flexible/maintainable than an explicit type. I mean, do you want to start typing

boost::multi_map<NodeType, indexed_by<ordered_unique<identity<NodeType>>, hashed_non_unique<identity<NodeType>, custom_hasher>>::iterator_type<0> it

That's not even the full type. I missed off a couple template arguments.

share|improve this answer
4  
+1 for the example, but that also tells something about the state of "modern" C++. –  zvrba May 12 '12 at 13:37
10  
@zvrba: Yeah- that the generic facilities are much more powerful than C#'s. –  DeadMG May 12 '12 at 13:47
    
that's what typedef is for –  gbjbaanb May 13 '12 at 11:51
11  
@gbjbaanb No, that’s what auto is for. By design. typedef helps, but auto helps more. –  Konrad Rudolph May 13 '12 at 13:13
add comment

YES, you should! auto does not erase the type; even if you "don't know" what x.begin() is, the compiler knows and will report an error if you try to use the type wrongly. Also, it is not unusual to emulate map with a vector<pair<Key,Value>>, so the code using auto will work for both dictionary representations.

share|improve this answer
add comment

Objection! Loaded question.

Can you explain to me why the third code has ?? in it, yet the first and second don’t? For fairness’ sake, your code must read as follows:

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->???
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->second->???
}

There. Same problem even though you didn’t use auto.

And in all cases, the answer is the same: Context matters. You can’t meaningfully talk about a piece of code in isolation. Even if you hadn’t used templates but some concrete type, this would only have moved the problem somewhere else, since the reader of your code would have to know about the declaration of said type.

If use of auto in those situations render your code unreadable you should treat this as a warning sign that there’s something wrong with your code design. Of course, there are cases where low-level details matter (such as when dealing with bit operations or legacy API) in which cases an explicit type might aid readability. But in general – no.

Regarding var (since you explicitly mentioned it), there’s also a vast consensus in the C# community for using var. Arguments against its use are generally built on fallacies.

share|improve this answer
add comment

PRO

Your code :

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

is not going to compile, because of the template dependent name.

This is the correct syntax :

for( typename std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

Now look how long the type declaration is. This tells why the auto keyword was introduced. This :

for( auto it = x.begin(); it != x.end(); i++)

is more concise. So, this is a pro.


CON

You have to be a bit careful. With the keyword auto, you get the type you declared.

For example :

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto it : v )
{
  ++ it;   // ops modifying copies of vector's elements
}

vs

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto & it : v )   // mind the reference
{
  ++ it;   // ok, vector's elements modified
}

To conclude : yes, you should it, but not overuse it. Some people tend to use it too much, and put auto everywhere, like in next example :

auto i = 0;

vs

int i = 0;
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.