Variadic Templates in C++ 11 (Part 2 of 2)

Last week we started discussing C++11’s new Variadic Templates.

In that article I showed you how to declare a function initialized by a Variadic Template that returns the number of template arguments it was called with. Today, we build on those concepts to implement a printf-like function with the properties of being typesafe, don’t requiring parsing formatting characters and supporting non-POD data types. Let’s get started.

The first thing I want to do is rewrite the example from last week. This will ease introducing this week’s concepts. Let’s create a new function g that does the same that f did, but receives any number of arguments via template instantiation.

template <class... T>
size_t g(T... args)
{
  return sizeof...(args);
}

g does exactly the same that f, the only difference is that we can now call it using the following syntax:

int main(int argc, char* argv[])
{
  cout << g(); // prints "0"
  cout << g(1); // prints "1"
  cout << g(1,2,3,4,5,6,7) // prints "7"
}

It is, in a way, like a variadic function, but written in C++11 style instead of plain C.

It’s important that you understand how g works, if you don’t, please review the code again and try making changes to it.

Assuming that’s out of the way, let’s delve in today’s article.

We want to develop a print function that can receive any number of parameters of any type. So we can call:


A a; // Create some object...

print(1);
print(1, 2.0f);
print(1, 2.0f, "Hello");
print(1, 2.0f, "Hello", a);

// An so on...

Now, you might be guessing that one way to implement this function would be to have a “base case” that can print one argument and then have it called with each supplied argument.

template <class T>
void print(const T& msg)
{
  cout << msg << " ";
}

That’s a really good idea and, last time, we saw how to determine how many arguments a Variadic Template has been instanciated with (using the sizeof… operator).

Unfortunately, when it comes to Variadic Templates, we can’t iterate over the arguments based on the count. We need to find another way.

In an idea that I regard largely borrowed from functional programming, what if we could separate the list of arguments in the “head” element and the “rest” of the list?

Well, if that was the case, then we could call our base-case print function with the head and then call the general-case function with the rest of the list. Eventually, the list will be empty and we will have printed all elements!

We can do exactly that using C++11 new template syntax:


// This is our base-case for the print function:

template <class T>
void print(const T& msg)
{
  cout << msg << " ";
}


// And this is the recursive case:

template <class A, class... B>
void print(A head, B... tail)
{
  print(head);
  print(tail...);
}

Let’s try this with a simple program:

int main(int argc, char* argv[])
{

  print(1, "\n");
  print(1, 2.0f, "\n");
  print(1, 2.0f, "Hello", "\n");

  return 0;
}

The output should be something like:

 1 
 1 2 
 1 2 Hello

And that’s all there is to it. The C++ compiler will take care of generating the appropriate code to instanciate our functions and to split the parameter list so we can print the arguments one by one. Notice how this is much easier than having to mess with variadic functions, while being typesafe too.

The biggest challenge is assimilating the new syntax, but there are lots of good references around like this article from IBM, where I got the idea of writing a print function, or even the Variadic Template proposal for the ISO committee, another great resource.

Stay tuned for more C++11 goodness next week!

Posted in C++

Variadic Templates in C++11 (Part 1 of 2)

This week we are continuing with the C++11 saga, moving on to a new feature called “Variadic Templates”.

Inspired by the concept of Variadic Functions in C, the idea behind Variadic Templates is to allow a template to be instanciated with any number of arguments.

In this article I’ll cover the new syntax and present a simple example that declares a function that uses a Variadic Template that prints the number of arguments it was intantiated with.

Previous parts of this saga included an overview of new iterators and lambda expressions as well as Move Semantics, which was treated in two parts: Part 1 and Part 2.

Let’s get started!

First of all, C++11 had to extend the C++ syntax for templates in order to support Variadic Templates. The new syntax allows annotating a parameter with an ellipsis (…) to denotate that we may expect receive zero or more parameters in the given place.

This means that the following declaration is now valid C++:

template <class... T>
void f()
{
}

f is a function that can be expanded with zero or more template parameters.

Now that we know how to declare a Variadic Template, let’s write a simple program that prints the number of arguments the function f template has been expanded with.

#include <iostream>
using std::cout;
using std::endl;

template <class... T>
size_t f()
{
    return sizeof...(T);
}

int main(int argc, char* argv[])
{
    cout << "sizeof f<int>" << f<int>() << "\n";
    cout << "sizeof f<int, float>" << f<int, float>() << "\n";
    cout << "sizeof f<int, float, char>" << f<int, float, char>() << endl;
    return 0;
}

Compiling this program with clang and running it produces the following output:

sizeof f<int>: 1
sizeof f<int, float>: 2
sizeof f<int, float, char>: 3

Here, each line of the output corresponds to the number of parameters the function template was instantiated with. As you probably noticed, the new sizeof… takes the packed template arguments and returns their count. If we just called f without instantiating its template, the number of arguments printed would be 0.

Now, you might be wondering what Variadic Templates might be used for. In next week’s article I will show you how to write a typesafe printf-like function in C++11 style. Stay tuned!

Posted in C++

Move Semantics in C++11 (Part 2 of 2)

Last week we talked about the problem with passing objects around in the 2003 C++ standard, and mentioned how the new move semantics in C++11 could help us avoid expensive object copies.

In this article I continue where I left off last week and show an updated version of the code that implements move semantics.

Now, the new code might be generated by a C++11 compiler automatically, just like default copy and assignment operators are generated, but I will show you how to implement these yourself.

Normally, we would just go about adding the new functions to our program, and that’s the way it should be for new C++11 codebases. Chances are, however, that today you will probably be adding support to an existing project that might need to be built for a platform that doesn’t have a readily available C++11 compiler.

You wouldn’t want to break compatibility with that platform, so something you can do is to conditionally compile move semantics into your program. This way, you can have the best of both worlds: a speedy implementation for programs compiled with a state-of-the-art compiler and a (slower, but working) fallback for all other target platforms.

So, bearing this in mind, let’s add a new move constructor and a new move assignment operator to A, but protected by a MOVE_CTOR macro:

#include <iostream>
using std::cout;
using std::endl;

class A
{
	public:
		A();
		A(const A& other);
		A& operator=(const A& other);

#ifdef MOVE_CTOR
		A(A&& other);
		A& operator=(A&& other);
#endif //MOVE_CTOR

		float _a;
};

A::A() : _a(0.0f)
{
	cout << "Running A()" << endl;
}

A::A(const A& other)
{
	cout << "Running A(const A&)" << endl;
	_a = other._a;
}

A& A::operator=(const A& other)
{
	cout << "Running operator=(const A&)" << endl;
	_a = other._a;
	return *this;
}

#ifdef MOVE_CTOR

A::A(A&& other)
{
	cout << "Move-constructing A" << endl;
	_a = other._a;
	other._a = 0.0f;
}

A& A::operator=(A&& other)
{
	if (&other != this)
	{
		cout << "Move-assigning A" << endl;
		_a = other._a;
		other._a = 0.0f;
	}

	return *this;
}

#endif //MOVE_CTOR

A getAnA()
{
	A a;
	a._a = 1.0f;
	return a;
}

int main(int argc, char* argv[])
{
	cout << "==Declaring A a==" << endl;
	A a; 
	cout << "==Assigning a=getAnA()==" << endl;
	a = getAnA();
	cout << "==done==" << endl;
	cout << "a._a = "<< a._a << endl;
	return 0;
}

To build this source file with support for move semantics, use the following command. Older compilers can opt-out of building C++11-specific code.

clang++ -std=c++11 -stdlib=libc++ -DMOVE_CTOR main.cpp

If everything's alright, here's the output that should be produced from running this program:

:@~/devel/C++/move_ctor11$ ./a.out 
==Declaring A a==
Running A()
==Assigning a=getAnA()==
Running A()
Move-assigning A
==done==
a._a = 1

Here we can immediately notice how we are avoiding running the (expensive) copy assignment operator and we substitute it with a lightweight move assignment that takes the internal data of the source object.

Think how this could help you avoid deep-copying matrices, trees, memory pages, and even how it would help you code safer by preventing having to sacrifice const-correctness and immutable object state in your code as hacky ways to gain performance. C++11 really does feel like a new language.

Stay tuned for more C++11 goodness next week!

Posted in C++

Move Semantics in C++11 (Part 1 of 2)

Continuing with the C++11 saga, this week I’ve been playing with move semantics. In this post I share my findings regarding using it on Apple’s Clang version 4.0.

Move semantics are a new mechanism built into C++ that allow us to “move” data from one object to another. They help avoid full object copies that, today, could occur under different scenarios.

The copy involved in passing in values to a function is a good example that can usually be avoided by receiving parameters as const references instead of as values. Other scenarios, like returning an object from a function, are, however, harder to avoid.

Move semantics let us write special functions that can “steal” a source object’s inner data and assign it to a new object. It could help you avoid an expensive copy operation when you know the source object is not going to be used anymore.

I’ve written a simple example to illustrate the problem. Suppose we have class A and we want to have a function that creates an A instance, then customizes it and finally returns it to the caller.

#include <iostream>
using std::cout;
using std::endl;

// A's interface:

class A
{
	public:
		// Default ctor:
		A();
		
		// Copy ctor:
		A(const A& other);

		// Copy-assignment operator:
		A& operator=(const A& other);

		// Inner data, should be private...
		float _a;
};

// A's implementation:

A::A() : _a(0.0f)
{
	cout << "Running A()" << endl;
}

A::A(const A& other)
{
	cout << "Running A(const A&)" << endl;
	_a = other._a;
}

A& A::operator=(const A& other)
{
	cout << "Running operator=(const A&)" << endl;
	_a = other._a;
	return *this;
}

// Helper function to create and customize an A instance:

A getAnA()
{
	A a;
	a._a = 1.0f;
	return a;
}

// Program entry point:

int main(int argc, char* argv[])
{
	cout << "==Declaring A a==" << endl;
	A a; 
	cout << "==Assigning a=getAnA()==" << endl;
	a = getAnA();
	cout << "==done==" << endl;
	cout << "a._a = "<< a._a << endl;
	return 0;
}

Running this code yields the following output:

:@~/devel/C++/move_ctor11$ ./a.out 
==Declaring A a==
Running A()
==Assigning a=getAnA()==
Running A()
Running operator=(const A&)
==done==
a._a = 1

The problem here lays in line 6. When the instance is to be returned from function getAnA(), it lives in the called function's stack, so we need to copy it into the caller's stack space in orde to return it. The code that does the copy is generated automatically by the C++ compiler and will incur in a performance penalty.

How slow is it? Well, it depends. For a big object (for instance a memory page, a huge matrix or other gigantic data structure) the performance penalty can be significant, specially when we really start to pass objects around.

This copy, however could completely be avoided by leveraging the fact that the source instance is going to go away. Move semantics allow us to have the destination A steal (or move) the source A's inner data.

Next week I'll show you how you can implement move semantics to speed up object passing. Stay tuned!.

Posted in C++