C++11 Variadic Templates Example

I wanted to write a function that takes a string containing a number of placeholders and a corresponding number of other parameters (perhaps non-pod) and returns a string with the placeholders replaced with stringified versions of the parameters:

For example:

	Format("I %%% about %%% of %%%","dream", 7, 9)

...would evaluate to...

	"I dream about 7 of 9"

...in a similar way to what...

	ostringstream os;
	os << "I " << "dream" << " about " << 7 << " of " << 9;
	return os.str();

...would do.

I'm using gcc 4.6 in -std=c++0x mode so Variadic Templates are available.

I haven't used Variadic Templates before. My first draft is below. It appears to work, but it's using a linear recursion. My question is, is there a way to write it iteratively?

Basically in my recursive solution I define...

    Format(s):
        output(s)

...as the base case and then...

    Format(s, head, tail...):
	divide s into three substrings:  (eg "foo %%% bar %%% baz")
		1. before_first_placeholder (eg "foo ")
		2. first_placeholder (eg "%%%")
		3. after_first_placeholder (eg " bar %%% baz")

	output(before_first_placeholder)
	output(head)
	output(Format(after_first_placeholder, tail))

...as the recursive case.

Working code and a test case is below. Feedback/thoughts appreciated.

// (C) 2011, Andrew Tomazos <http://www.tomazos.com>

#include <string>
#include <sstream>
#include <iostream>

using namespace std;

class StringFormatException {};

const string g_sPlaceholder("%%%");

template <class ... T>
inline string Format(const string& sFormat, const T& ...);

template <class ... T>
inline string Format(const string& sFormat)
{
        size_t iFirstPlaceholderPos = sFormat.find(g_sPlaceholder);

        if (iFirstPlaceholderPos != string::npos)
                throw StringFormatException();

        return sFormat;
}

template <class Head, class ... Tail>
inline string Format(const string& sFormat, const Head& head, const Tail& ... tail)
{
        stringstream os;

        size_t iFirstPlaceholderPos = sFormat.find(g_sPlaceholder);

        if (iFirstPlaceholderPos == string::npos)
                throw StringFormatException();
        else
        {
                string sFront(sFormat, 0, iFirstPlaceholderPos);
                string sBack(sFormat, iFirstPlaceholderPos + g_sPlaceholder.size());

                os<< sFront << head << Format(sBack, tail ... );
        }

        return os.str();
}

int main()
{
        if (Format("I %%% about %%% of %%%","dream", 7, 9) == "I dream about 7 of 9")
                cout << "pass" << endl;
        else
                cout << "fail" << endl;

        return 0;
}

Tested as follows:

	$ cat > test.cpp
        <paste above>
	$ g++ --version
	g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
	$ g++ -std=c++0x test.cpp
	$ a.out
	pass

Enjoy,
  Andrew.

--
Andrew Tomazos <andrew@tomazos.com> <http://www.tomazos.com>