C++ programming on Cloud 9

A weblog dedicated to Visual C++, interoperability and other stuff.

C++0x step by step: auto

With this short post, I am kicking off my new series of articles on the new C++ standard implementation in Visual C++ 2012. These articles will all be short, covering a single new thing each. This way you can see the impact of each change or improvement all by itself. That is easier to read, and of course also easier for me to write.

For the first article, I picked auto, simply because its impact on existing code bases is huge, and literally every C++ programmer can take advantage of it. For those who don't yet know it: auto can be used as the variable type when declaring local variables, instead of the explicit type. The end result is still a strongly typed variable, because the compiler knows what the type of that variable has to be. It just doesn't force you to type it yet again.

So you can use

 auto localvar = foo();

Instead of

MyType* localvar = foo();

It is much more convenient to use auto, because you no longer have to think about typing the right name. What makes it doubly useful is if during development, the return type of 'foo' changes, the change is transparent in your code. As long as the semantics of that return type stay the same, it will compile properly.

To give a more practical example: consider a simple vector with a template data type such as can be found in many C++ projects that make use of the STL. The really ugly thing about it is the need for an iterator. Even for such a simply example, the iterator type declaration is ugly. And if you ever need to update the type, it will involve a lot of work. Consider the following type: vector < MyData < int> > data; In order to iterate through that vector, we need the following loop:


for(vector < MyData< int > > ::iterator i = data.begin(); i< data.end(); i++)
{
   
cout << i->a << endl;
}

 

 

As you can see, it is ugly. A traditional way to deal with this is to create typedefs for all iterator types that you use in your code. This works, but you still need to do that work. The typedefs are just a way to move the ugliness into a header file where you don't notice it. And with typedefs you can still introduce some errors. C++0x otoh can use the auto keyword.

for

 

 

(auto i = data.begin(); i< data.end(); i++)
{
    cout << i->a << endl;
}

And this makes the resulting source code not only much easier to read (for the maintainer) but also easier to write, and if the type of 'data' should change, then as long as the public interface is compatible with before, the code will just compile without needing syntax modifications.

 

Posted: Mon, Jul 2 2012 14:42 by vanDooren | with 2 comment(s)
Filed under: , ,

Comments

CppJohn said:

A couple of small suggestions:

It's better to increase the iterator with prefix ++ instead of postfix ++, i.e.: use "++i" instead of "i++".

Moreover, it seems that non-member begin() and end() are the preferred form: "begin(data)" and "end(data)".

See also: herbsutter.com/elements-of-modern-c-style

(Of course with range for there is no need for this stuff, but I suspect it will be the subject of another blog post :)

# July 3, 2012 5:13 AM

vanDooren said:

Thanks for the feedback. Prefix vs postfix does indeed have an impact. I have to admit that I usually don't pay attention to it because the impact is so small.

You are right about non member functions and the range for, and these are indeed for the next posts :-)

by keeping it limited to 1 thing per post it is easier to write. 15 minutes to half an hour is an ideal period to fire up VS, make a small sample program and write / try something. For long articles, you need 15 minutes just to figure out what you were doing previously.

# July 3, 2012 7:31 AM