Variadic template example in C++0x

I must have been living under a rock because I’d been unaware of all the cool additions being added in C++0x. I thought I’d do a series of examples showing simple use of several of these. This one is about variadic templates, namely, templates that can have any number of types associated with them.

So not only can you do:

<typename T> int my_function(T arg) {...}

But you can do this:

<typename T, typename... Args> in my_function(T arg, Args the_rest) {...}

Wikipedia has a good overview, so I’ll direct you there for more. I’m essentially copying their printf example, but I had a few issues compiling it, so for completeness I’ll mention them here:

#include <stdexcept>
#include <iostream>

void mprintf(const char* s)
{
    while (*s) {
        if (*s == '%' && *(++s) != '%')
            throw std::runtime_error("invalid format string: missing arguments");
        std::cout << *s++;
    }
}
 
template<typename T, typename... Args>
void mprintf(const char* s, T value, Args... args)
{
    while (*s) {
        if (*s == '%' && *(++s) != '%') {
            std::cout << value;
            mprintf(s, args...); // call even when *s == 0 to detect extra arguments
            return;
        }
        std::cout << *s++;
    }
    throw std::logic_error("extra arguments provided to printf");
}

int main(int argc, char** argv) {
    std::string s("test");
    std::string s2("test2");
    mprintf("% - %", s, s2);
    return 0;
}

Compile with:

gcc -std=c++0x -lstdc++ file.cc -o vtemplate-example

If you run the executable vtemplate-example you should get the output “test – test2″.

A couple of notes:

  • I renamed printf (used in the wikipedia example) to mprintf because the compiler complained about the call to the overloaded printf being ambiguous.
  • If you are on OSX, make sure you have gcc-4.4 installed and that you invoke it instead of the Apple gcc. If you try to use the Apple version of gcc it won’t understand the -std=c++0x option.

I hope to play with lambda functions sometime soon too.



4 comments ↓

#1   Jason McCandless on 07.20.11 at 4:46 am

Just a quick note:

Should be linked with “-lstdc++”, not “-lstd++”.

#2   Joel on 07.20.11 at 1:24 pm

Well spotted Jason – I have updated the post.

#3   Zeke on 12.10.11 at 2:44 pm

Why don’t you create your own example, rather than using the same example from the C++11 wikipedia page.

#4   Joel on 12.10.11 at 2:46 pm

Zeke – as I wrote in my post it was because the wikipedia example didn’t actually compile.

Leave a Comment