Writing a Mac OS X Screensaver

A screensaver can be seen as a zero-player game used mostly for entertainment or amusement when the computer is idle.

A Mac OS X screensaver is a system plugin. It is loaded dynamically by the Operating System after a given time has elapsed, or embedded into a configuration window within the Settings App.

What is a system plugin? It means we basically write a module that ascribes to a given interface and receives callbacks from the OS to perform an operation. In this case, draw a view.

A custom screensaver that uses OpenGL to render a colorful triangle.
A custom screensaver that uses OpenGL to render a colorful triangle.

Writing a Mac OS X screensaver is surprisingly easy. A special class from the ScreenSaver framework, called ScreenSaverView, provides the callbacks we need to override in order to render our scene. All work related to packing the executable code into a system component is handled by Xcode automatically.

We can render our view using either CoreGraphics or OpenGL. In this sample, I’m going to use OpenGL to draw the scene.

Initialization and Lifecycle Management

We start off by creating a View that extends ScreenSaverView:

#import <ScreenSaver/ScreenSaver.h>

@interface ScreensaverTestView : ScreenSaverView

@property (nonatomic, retain) NSOpenGLView* glView;

- (NSOpenGLView *)createGLView;

@end

Let’s move on to the implementation.

In the init method, we create our OpenGL Context (associated to its own view). We’ll also get the cleanup code out of the way.

- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
    self = [super initWithFrame:frame isPreview:isPreview];
    if (self)
    {
        self.glView = [self createGLView];
        [self addSubview:self.glView];
        [self setAnimationTimeInterval:1/30.0];
    }
    return self;
}

- (NSOpenGLView *)createGLView
{
	NSOpenGLPixelFormatAttribute attribs[] = {
		NSOpenGLPFAAccelerated,
		0
	};
	
	NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
	NSOpenGLView* glview = [[NSOpenGLView alloc] initWithFrame:NSZeroRect pixelFormat:format];
	
	NSAssert(glview, @"Unable to create OpenGL view!");
	
	[format release];
	
	return [glview autorelease];
}

- (void)dealloc
{
	[self.glView removeFromSuperview];
	self.glView = nil;
	[super dealloc];
}

The above code is self-explanatory.

Notice how we tell the video driver what kind of OpenGL configuration it should allocate for us; In this case, we only request hardware acceleration. We won’t allocate a depth buffer because there is no need for it (yet).

Rendering Callbacks

Now, let’s move on to implementing the rendering callbacks for our screensaver. Most of the methods here will just forward the events to the super class, but we’ll customize the animateOneFrame method in order to do our rendering.

- (void)startAnimation
{
    [super startAnimation];
}

- (void)stopAnimation
{
    [super stopAnimation];
}

- (void)drawRect:(NSRect)rect
{
    [super drawRect:rect];
}

- (void)animateOneFrame
{
	[self.glView.openGLContext makeCurrentContext];
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);
	
	static float vertices[] = {
		1.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		-1.0f, -1.0f, 0.0f
		
	};
	
	static float colors[] = {
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f
	};
		
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glEnableClientState(GL_VERTEX_ARRAY);
	glColorPointer(3, GL_FLOAT, 0, colors);
	glEnableClientState(GL_COLOR_ARRAY);

	glDrawArrays(GL_TRIANGLES, 0, 3);

	glDisableClientState(GL_COLOR_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);
	
	glFlush();
	[self setNeedsDisplay:YES];
    return;
}

- (void)setFrameSize:(NSSize)newSize
{
	[super setFrameSize:newSize];
	[self.glView setFrameSize:newSize];
}

We place our rendering logic in the animateOneFrame method. Here, we define our geometry in terms of vertices and colors and submit it as vertex arrays to OpenGL.

Implementing the setFrameSize: method is very important. This method is called when our screensaver starts and we must use it to adjust our views’ dimensions so we can render on the whole screen.

Actionsheet Methods

Mac OS X screensavers may have an associated actionsheet. The actionsheet can be used to let the user customize the experience or configure necessary attributes.

- (BOOL)hasConfigureSheet
{
    return NO;
}

- (NSWindow*)configureSheet
{
    return nil;
}

Testing our Screensaver

Unfortunately, we can’t run our screensaver right off Xcode. Because it’s a system plugin, we need to move its bundle to a specific system folder so Mac OS X can register it. In order to install the screensaver just for ourselves, we place the bundle in the $HOME/Library/Screen\ Savers directory.

Once copied, we need to open the Settings App (if it was open, we need to close it first). Our screensaver will be available in the “Desktop & Screen Saver” group, under the “Other” category.

Conclusion

Screensaver writing for Mac OS X is surprisingly easy! With the full power of desktop OpenGL and C++ at our disposal, we can create compelling experiences that delight users and bystanders.

As usual, there are some caveats when developing OS X screensavers. You can read about them here.

Happy coding!

More on Objective-C Blocks

In 2011 I first blogged about Objective-C blocks, a game changing language construct that allows defining callable functions on-the-fly. In this post, we delve into some advanced properties of blocks in the Objective-C language.

1. Blocks capture their enclosing scope

Consider the following code snippet:

#import <Foundation/Foundation.h>

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

		int capture_me = 10;

		int (^squared)(void) = ^(void){
			return capture_me * capture_me;
		};


		printf("%d\n", squared());

	}
	return 0;
}

In the above example, we create a block that captures local variable “capture_me” and store it into a variable called “squared”. When we invoke the “squared” block, it will access the captured variable’s value, square it and return it to the caller.

This is a great feature that allows referencing local variables from deep within a complex operation’s stack. As Miguel de Icaza points out, however, we need to be careful with this feature to avoid producing hard to maintain code.

As you may have guessed, the code above correctly prints value “100”.

2. Blocks can modify captured variables

Now, consider this snippet. We will change our block not to return the squared variable, but rather to capture a reference to the local variable and store the squared value, overriding the original.

#import <Foundation/Foundation.h>

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

		__block int modify_me = 10;

		void (^squared)(void) = ^(void){
			modify_me *= modify_me;
		};


		squared();
		printf("%d\n", modify_me);

	}
	return 0;
}

The __block keyword signals that variable “modify_me” is captured as a reference by the Block, allowing it to be modified from within its body.

Just like before, this code still prints “100”. If we were to call the “squared” block a second time, we would square the variable again, yielding “10.000”.

3. Blocks are Objective-C Objects allocated on the stack

Unlike any other object instance in Objective-C, blocks are objects that are allocated on the stack. This means blocks need to be treated as a special case when we want to store them for later usage.

As a general rule of thumb: you should never retain a block. If it is to survive the stack frame where it was defined, you must copy it, so the runtime can place it on the heap.

If you forget and accidentally retain a block on the stack it might lead to runtime errors. The Xcode analyzer, thankfully, detects this problem.

Conclusion

If there were a feature I could have added to the Java programming language (when developing Android apps), it would without be, without a doubt, support for blocks or, in general, lambda expressions.

Objective-C blocks are a powerful feature that must be handled with care. When used correctly, they have the power to let us improve our code to make it more streamlined. When used incorrectly, they can lead to unreadable code and/or hard-to-debug memory-management bugs.

If you are interested in learning more about blocks in the Objective-C programming language, this article is a great resource and here’s the official Apple documentation.

Happy coding!

C++11 Enum Classes

With the release of the C++11 standard, C++ finally obtained its own enum type declarations. Dubbed “enum classes”, these new enums type define a namespace for the discrete values they contain. This sets them apart from classic C-style enums, which define their values in the enclosing scope. Enum classes can also be forward declared, helping improve compilation times by reducing transitive header inclusion.

C-style enums

So, what was the problem with C-style enums? -Consider this classic C enum defined at file scope:

enum ProjectionType
{
    PERSPECTIVE,
    ORTHOGONAL
};

Constants PERSPECTIVE and ORTHOGONAL are defined in the global namespace, meaning that all references to these names will be considered a value belonging to this enum. Using general names will surely lead to chaos, as two enums defined in different headers can easily cause type ambiguities when pulling both headers together in a compilation unit.

A solution to this problem in a language that does not have namespaces, like C, is to prefix each constant with something that identifies the type, as to prevent possible name clashes.

This means our constants would become PROJECTION_TYPE_PERSPECTIVE and PROJECTION_TYPE_ORTHOGONAL. Needless to say, all caps might not be ideal from a code readabilty standpoint, as they can easily make a modern C++ codebase look like an old C-style macro-plagued program.

The pre-2011 C++ approach

In C++, we do have namespaces, so we can wrap our enums in namespace declarations to help organize our constants:

namespace ProjectionType
{
    enum Enum
    {
        Perspective,
        Orthogonal
    };
}

Now, this is better. With this small change, our constants can be referenced as: ProjectionType::Perspective and ProjectionType::Orthogonal. The problem here is the fact that doing this every time for every enum can get a little tedious. Furthermore, our datatype is now called ProjectionType::Enum, which is not that pretty. Can we do better?

The C++11 solution

The ISO Committee decided to take this problem on by introducing the new concept of “enum classes”. Enum classes are just like C-style enums, with the advantage that they define a containing namespace (of the same name of the enum type) for the constants they declare.

enum class ProjectionType
{
    Perspective,
    Orthogonal
};

Notice we declare an enum class by adding the class keyword right after the enum keyword. This statement, which would cause a syntax error in the C++98 standard, is how we declare enum classes in C++11. It must be accepted by all conforming compilers.

Using this declaration, our constants can now be accessed as ProjectionType::Perspective and ProjectionType::Orthogonal, with the added advantage that our type is called ProjectionType.

C-style enums vs enum classes

Because C++ is a superset of C, we still have access to C-style enums in C++11-conforming compilers. You should, however, favor enum classes over C-style enums for all source files that are C++ code.

The Mandelbrot Project

I’ve published the source code of the program I wrote for my tech talk at the 2011 PyDay conference. It’s a Python script and a companion C library that calculates and draws the Mandelbrot set.

The objective of the tech talk was to show how to speed up Python programs using the power of native code.


A render of the Mandelbrot set as performed by the mandelbrot.py script. Computations were performed in C.
A render of the Mandelbrot set as performed by the mandelbrot.py script. Computations were performed in C.

What’s interesting about this program is that, although the core was written completely in Python, I wrote two compute backends for it: one in Python and one in C. The C code is interfaced with using the ctypes module.

The results of running the program are shown in the screenshot above. If you are interested in trying it, the full source code is hosted in GitHub, here: https://github.com/alesegovia/mandelbrot. I’ve licensed it under the GPLv3, so you can download, run it, test it and modify it.

As one would anticipate, the C implementation runs much faster than the Python one, even when taking into account the marshaling of objects from Python to C and back. Here’s the chart I prepared for the conference showing the specific numbers from my tests.

These tests were performed to compare the run times at different numer of iterations, note this is a logarithmic scale.


Comparison of the Python + C implementation vs a pure Python one. Scale is Logarithmic.
Comparison of the Python + C implementation vs a pure Python one. Scale is Logarithmic.

As you can see, Python programs can be significantly sped up using ctypes, especially when we are dealing with compute-intensive operations.

It might be possible to speed up the Python implementation to improve its performance to some extent, and now that the source code is available under the GPL, you are encouraged to! I would always expect well-written C code to outperform the Python implementation, but I would like to learn about your results if you happen to give it a go.

Happy hacking!

On Java, C#, Objective-C and C++

Objective-C, image taken from bigspaceship.com.
Objective-C, image taken from bigspaceship.com.

I’ve been meaning to write about this for a while. It’s something that comes up rather frequently at work, so I though I’d write it down to organize what’s on my mind.

Contrary to what many may think, the Java and C# languages are not based on C++ as much as on Objective-C. Indeed, Objective-C was a big influence in the design of the Java programming language. And since C# 1.0 was basically Microsoft’s Java, we shall consider it another derived language too.

So, why do people think of Java as a C++-derived language? Java was built on C++’s syntax, this is why Java code “looks like” C++ code. Java’s semantics, however, are heavily based on Objective-C’s.

Some Java and C# features borrowed directly from Objective-C include:

  • Dynamic binding.
  • Dynamic loading.
  • Single inheritance.
  • Interfaces (called “protocols” in Objective-C).
  • Large runtime.
  • “Class” objects.
  • Reflection.
  • Objects cannot be allocated in the stack.
  • Garbage Collection (deprecated in Objective-C).
  • All methods virtual by default (Java).
  • Properties (C#).
  • int, float, double, etc. wrapper classes.

Patrick Naughton, one of the original designers of the Java programming language, confirms this story in this discussion on usenet:

Usually, this kind of urban legend stuff turns out to be completely inaccurate, but in this case, they are right on. When I left Sun to go to NeXT, I thought Objective-C was the coolest thing since sliced bread, and I hated C++. So, naturally when I stayed to start the (eventually) Java project, Obj-C had a big influence. James Gosling, being much older than I was, he had lots of experience with SmallTalk and Simula68, which we also borrowed from liberally.

The other influence, was that we had lots of friends working at NeXT at the time, whose faith in the black cube was flagging. Bruce Martin was working on the NeXTStep 486 port, Peter King, Mike Demoney, and John Seamons were working on the mysterious (and never shipped) NRW (NeXT RISC Workstation, 88110???). They all joined us in late ’92 – early ’93 after we had written the first version of Oak. I’m pretty sure that Java’s ‘interface’ is a direct rip-off of Obj-C’s ‘protocol’ which was largely designed by these ex-NeXT’ers… Many of those strange primitive wrapper classes, like Integer and Number came from Lee Boynton, one of the early NeXT Obj-C class library guys who hated ‘int’ and ‘float’ types.

So, next time you look at Objective-C thinking how weird its syntax looks, remember this story and consider how much it influenced the programming language landscape.

Shadow Mapping on iPad

I’ve implemented shadow mapping on the MD2 Library using the Vortex Engine for iOS wrapper. Shadow mapping is a technique originally proposed in a paper called “Casting Curved Shadows on Curved Surfaces” [1], and it brought a whole new approach to implementing realtime shadows in 3D Apps.

Shadow mapping on iPad. The shadow is calculated in realtime and animates as the model moves.
Shadow mapping on iPad. The shadow is calculated in realtime and animates as the model moves.

Implementing shadow mapping on iOS is by nature a problem that spans several programming languages. Objective-C for creating the UI, C/C++ for interfacing with OpenGL and GLSL for implementing the technique in the GPU’s fragment shader.

The math involved in shadow mapping spans all of these languages, with different coordinate space transformations being implemented in the language appropriate to the pipeline stage we’re working on. This makes the technique a little tricky to implement the first time you attempt to.

Here is another screenshot of the technique running on an actual iPad. Notice how the shadow is cast on the floor as well as on top of the crate in the background.

Upfront capture of the shadow mapping technique running on the iPad simulator.
Upfront capture of the shadow mapping technique running on the iPad simulator.

Shadow mapping will be coming up in the next version of the MD2 Library app.

[1] – Lance Williams – Casting Curved Shadows on Curved Surfaces. http://artis.imag.fr/~Cyril.Soler/DEA/Ombres/Papers/William.Sig78.pdf

Fiddling with the HTML5 Canvas

I’ve been doing some experimenting with HTML5’s Canvas element. After some brushing up on Javascript, I started working on a couple of proof-of-concept scripts to see how well the platform can be used.

I have not been disappointed. Javascript, as a language, has evolved quite a bit since the old days of document.write(), with DOM editing as the one true way to manage dynamic content. Having said that, I find that Javascript is still quirky and flawed.

Here’s a short script I wrote (fewer than 160 lines) that animates a girl wearing the traditional Oktoberfest outfit. She walks back and forth within a given 500×500 area. This is not a video, your browser is doing the math to update her animations and move her around in realtime!

You should be able to see the demo just above this message, if you have a fairly recent browser that supports the HTML5 Canvas element. I was actually surprised about how mainstream Canvas support is: Chrome ≥ 22, Firefox ≥ 15, IE ≥ 9; Opera ≥ 12.1; Safari ≥ 5.1, Android ≥ 2.1 and Safari Mobile ≥ 3.2, all support this new element.

The animation atlas was taken from this cool website with resources free to use. The script “slices” the image, taking the appropriate frames to draw depending on the time simulation and the direction the character is walking towards (left or right).

Sprite animation atlas.
Sprite animation atlas.

Despite Javascript’s gotchas, with the addition of the HTML5 Canvas element, it’s become a nice tool that allows hacking together some easy 2D (or even 3D!) graphics and display them in a browser.

See you next time!

Function Objects using Variadic Templates in C++11

One of the biggest features introduced in C++11 are lambda expressions. Lamba expressions (or “lambdas”) are a powerful mechanism that allows defining functions “on-the-fly”. These can be stored in function objects and then be used by an object that doesn’t want to reveal its internal implementation, as well as to perform tasks on a parallel thread.

I was wondering how function objects could be implemented using other constructs of the language, mostly to see how much the language had to be changed in order to accomodate them. In this post I will show how to implement function objects using nothing but C++11’s variadic templates.

Variadic templates were introduced in our previous post in this C++11 series. This post will help pave the way for us to move into the more advanced topic of lambda expressions and std::function objects.

Function Pointers in C

As far as I can tell, C has always had functions as first-class citizens. Although their syntax is vastly different from the way one declares variables of other types, you could always define a variable that can be assigned a pointer to a function.

#include <stdio.h>
void print_number(int number)
{
    printf("Argument is: %d\n", number);
}

int main(int argc, char* argv[])
{
    void (*f)(int);  // f is a variable that can 
                     // store a pointer to a 
                     // function that receives 
                     // an int an returns nothing.
    f = print_number // legal.

    f(1024);         // calls print_number.  

    return 0;
}

Because C is a statically-typed language, we must be very careful with the types we declare f with, otherwise the assignment may be deemed invalid by the compiler.

Another problem is that the syntax can be cumbersome to remember and handle. Notice how the name of the variable is declared within the associated types.

Function Objects in C++

Unless you were using boost, C++ never had its own version of function objects until C++11. Programmers had to rely on the traditional C construct or write functors, classes that implement operator() and allow mimicking a function’s behavior.

Unlike C function pointers, functors are more readable, but we need to declare a class and implement operator() inside it. It’s much more verbose.

C++11 introduced the standard std::function type, which allows encapsulating a function declared by lamba expressions (or by other means). In production code, you will most certainly want to use std::functions. In this post, however, because of academic interest only, we’re going to exercise C++11’s variadic templates by implementing a generic function wrapper object called alg::function.

alg::function

Using variadic templates, it’s very easy to implement a simple function wrapper capable of handling any function type. I’m going to implement my solution using C function pointers. Remember: in C++11 production code, you will never do this.

namespace alg
{
    template <typename R, typename... T>
    class function
    {
        public:
            function(R (*f)(T...)) { _f = f; }
            R operator()(T... args) {return _f(args...);}
		
        private:
            R (*_f)(T...);

    };
}

And that’s all there is to it, really. Let’s go over the code.

I declare the class alg::function as a template that is to be instanciated by two parameters: a return type dubbed “R” and a list of types which I will refer to as “T”. The list of types can be empty, the return type is mandatory.

alg::function objects will have a single private member that is declared to be a pointer to a C function that returns a value of type R and receives the list of argument types T.

The only two additional methods that we need are: a public constructor that receives the function to wrap, storing it, and operator(), which will let us call the function. Notice how easily we can unpack the arguments when we call _f.

Instancing Examples

Let’s see it in action!

These samples illustrate the basic idea without complex data structures. It is certainly possible to pass alg::function objects around as the first-class citizens that they are, as well as passing-in and returning arbitrary C++ objects and structs from these wrappers.

The only limitation is the fact that we don’t support const parameters. Adding support for them would require tweaking the alg::function class a bit more. We leave this as an exercise to the reader.

A single function that receives an int and prints it:

void fun(int arg)
{
    std::cout << "hello from fun! (arg=" 
              << arg 
              << ")"
              << std::endl;
}

int main(int argc, char* argv[])
{
    alg::function<void, int> f(fun);

    f(0); // prints "hello from fun! (arg=0)"
}

A function that receives no parameters:

void fun2()
{
    std::cout << "hello from fun 2!" << std::endl;
}

int main(int argc, char* argv[])
{
    alg::function<void> f2(fun2);

    f2();  // prints "hello from fun 2!"
}

A function that receives two std::string instances and prints them together:

void fun4(std::string msg1, std::string msg2)
{
    std::cout << "hello from fun 4! (concat=" 
              << msg1 << msg2 
              << ")" 
              << std::endl;
}

int main(int argc, char* argv[])
{
    alg::function<void, std::string, std::string> f4(fun4);

    f4("hello, ", "world!"); // prints "hello from fun 4! (concat=hello, world!)"
}

Conclusion

Variadic templates offer a lot in terms of flexibility and allow us to extend the language even further than it was possible before. Remember, these examples are just food for thought. In C++11 production code, you will most certainly want to use std::function objects and lambda expressions.

See you next time!

Other articles in this C++11 series

libsdl-1.2 support for OpenGL 3.2

This week we take a break from the C++ saga to talk a little about OpenGL. I’ve forked libsdl-1.2 and added support for creating OpenGL 3.2 forward-compatible contexts. This is something that could be deemed helpful until libsdl 2.0 is released.

You can find the source code on my GitHub page, at: github.com/alesegovia. In so far, only the Mac platform is supported, as it’s the only Operating System I currently have access to. I’ll hopefully be able to add Linux support as soon as I can get hold of a Linux box with a suitable video card.

Creating an OpenGL 3.2 compatible context is very simple. Once you have downloaded, compiled and installed libsdl-1.2-gl, you just need to create your window using the new SDL_OPENGLCORE flag.

This sample program creates an OpenGL 3.2 context, displays the OpenGL version number and exits:

#include <SDL.h>
#include <stdio.h>
#include <OpenGL/gl.h>

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

    SDL_Surface* pSurface = SDL_SetVideoMode(600, 600, 32, SDL_OPENGL|SDL_OPENGLCORE);

    printf("GL Version:%s\n", glGetString(GL_VERSION));

    SDL_Quit();

    return 0;
}

You need to be running Mac OS X Lion or higher in order to be able to create OpenGL 3.2 contexts. If you are running Snow Leopard or your video card does not support OpenGL 3.2, you might get a Compatibility profile and your OpenGL version might be stuck on 2.1.

Also note that Mac OS X reports the OpenGL version to be 2.1 unless you specifically create forward-compatible OpenGL contexts, so if you need to know whether your Mac supports OpenGL 3.2, you can look your system configuration up in this great table maintained by Apple.

If you find this useful, let me know in the comments. Enjoy!

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!