TechWire

Tag - C++

The perfect swap in C++

So you are coding this cool app and you need to swap two variables. How does a good programmer do that in C++? The STL (Standard Templates Library) provides the std::swap function which does exactly what we want.

[code language=”cpp”]int a = 10;
int b = 12;
std::swap(a, b);[/code]

That’s easy. But hey, why don’t we go ahead and see actually what std::swap does behind the scenes? A grep in the Apache STL implementation gives us:

[code language=”cpp”]template <class _TypeT>
inline void swap (_TypeT& __a, _TypeT& __b)
{
   _TypeT __tmp = __a;
   __a = __b;
  __b = __tmp;
}[/code]

Woah, all the underscores! But don’t panic just yet. All it does is the grade-school swapping:

[code language=”cpp”]T tmp = a;
a = b;
b = tmp;[/code]

Hmm. That is perhaps the most straight-forward swap implementation. But how does it perform? Look again.

[code language=”cpp”]T tmp = a; // a copy of ‘a’ is created
a = b;  // a copy of ‘b’ is created
b = tmp;  // a copy of ‘tmp’ is created[/code]

That’s a lot of copies for a simple function! What if we could just ‘swap’ the two values without copying?

We google around a bit and find out that the above std::swap implementation is actually the old way of doing things. The new C++11 implementations does this differently. So we check the C++11 include files.

[code language=”cpp”]template<typename _Tp>
  inline void
swap(_Tp& __a, _Tp& __b)
   {
   _Tp __tmp = _GLIBCXX_MOVE(__a);
  __a = _GLIBCXX_MOVE(__b);
   __b = _GLIBCXX_MOVE(__tmp);
  }[/code]

That’s more confusing than the previous one. Again, don’t panic. We can simplify the things. _GLIBCXX_MOVE is defined to be std::move. Let’s just call it ‘move’. So the above function is roughly similar to:

[code language=”cpp”]T tmp = move(a);
a = move(b);
b = move(tmp);[/code]

Now we are scratching our chins. At first glance, the implementation looks much similar to the grade-school swap. And then, there’s this move-thingy. Okay, looking back, we remember that the elements were ‘copied’ in the grade-school algorithm. Instead, it looks like the variables are ‘moved’ here.

And we are right! In the first line, tmp is set to the value of a, while the variable a is (temporarily) invalidated. No copying is done. The previous memory location of a is now the territory of tmp. In the next line, a is set to the value of b, while b is invalidated. Finally, b is set to the value of tmp, and tmp itself is invalidated, which we don’t need again anyway. And the result? The two values are swapped without any copy operations!

How does this moving really work? C++11 introduces the so called “rvalue references”. The ‘move’ function returns the rvalue of the input parameter without triggering a copy construction.

[code language=”cpp”]T &a = x; // normal (lvalue) reference
T &&b = y; // rvalue reference [/code]

A full description will not fit in this post, but you can go through this nice little introduction on rvalue references. You might also want to refresh your memory about lvalues and rvalues.

And let’s call it a day and meet again with another little C++ adventure.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html

Auto-matic typing in C++

C++ is a statically typed language by design. In other words, you have to specify which data type your dear variable is supposed to be. If you declare myCoolVar to be an integer, you can’t let him play with his string friends. Type checking is done at the compile time. So myCoolVar will soon be caught red-handed if it goes matchmaking with a string or a vector.

This is contrast to the radical kids in the block like Python and Ruby who don’t care whom their variables play with. They call themselves dynamically-typed. A washed up floating point might become a variable with a character in a few moments.

Cool as it may sound, dynamic typing is not for everyone. C++ is mostly used where performance and reliability are key factors. Thus the C++ standard has always insisted on strong, static typing. But even if you haven’t been programming since the dinosaurs roamed the earth, you may know that it’s not always easy to remember and explicitly declare the correct variable type. The new C++ standard, or C++11  as it’s known, aims to change this.

C++11 isn’t exactly new to the city. Most compilers around, including gcc and Microsoft C++ compilers, now include support for C++11. Among the dozens of improvements it has brought, let’s have a look at the auto keyword.

Suppose you want to take the length of a C++ string called myStr. Easy-peasy. myStr.length() is the way to go. But wait. The return value of the length() function is string::size_t. Besides from being hard to type in, it’s not easy to remember all these return types either. That’s when the auto keyword comes handy. Instead of,

[code language=”cpp”]string::size_t len = myStr.length();[/code]

you can simply write

[code language=”cpp”]auto len = myStr.length();[/code]

The compiler detects the return type of myStr.length() and makes len a variable of that type. So very convenient.

Not convinced? Suppose you have a map of objects that you need to iterate. How do you initialize the iterator?

[code language=”cpp”]std::map<char,int>::iterator it = myMap.begin();[/code]

Ugh. That isn’t the nicest code snippet you’ve written. But hey, we have our friend auto:

[code language=”cpp”]auto it = myMap.begin();[/code]

Skadoosh! Auto has automagically made it an std::map<char,int>::iterator, because that’s the return type of myMap.begin()! Now that does look nice.

What if I want to declare a variable with a default value?

Suppose you want to declare a variable that holds the length of a string. But you first need to set it to zero.

[code language=”cpp”]auto len = 0;[/code]

Ha! That is wrong! This would make len an int, not string::size_t. But C++11 has an answer for that as well. You can use the decltype keyword like this:

[code language=”cpp”]decltype(myStr.size()) len = 0;[/code]

This declares len as a variable of type returned by myStr.size(), but still initializes it to zero.

Is this dynamic typing?

No, not really. Even though it appears as if auto changes a variable’s type dynamically, it actually happens during the compile time. It’s just that you don’t have to explicitly code the type of the variable, the compiler does that for yourself. Which is mighty sweet of C++11.

Is it safe to use auto?

Isn’t letting your variables roam free considered as bad parenting? No. Not only is it safe to use auto in your C++ code, it’s even recommended that you use it wherever possible. Bjarne Stroustrup, the creator of the C++ language himself, advocates its use. Just make sure that your compiler is updated to support C++11.

Image Credits : http://geekandpoke.typepad.com/geekandpoke/2010/01/best-of-both-worlds.html