I've written the following code to produce a formatted string (similar, but not identical to the formatting style that System.String.Format() does in .Net), using a combination of boost and the new variadic templates that C++11 offers. I'm looking for criticism, advice, and suggestions for improvement.

Please note: much of the code for handling type-specific formatting is not done. please do not comment on this, unless you have suggestions for its implementation.

Code:
#include <sstream>
#include <stdexcept>
#include <boost/lexical_cast.hpp>

template<typename T>
std::string BasicToString(const T& t)
{
	return boost::lexical_cast<std::string>(t);
}

inline std::string Convert(const std::string& fmt, const int& i)
{
	return BasicToString(i); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const long& l)
{
	return BasicToString(l); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const long long& l)
{
	return BasicToString(l); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const unsigned& u)
{
	return BasicToString(u); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const unsigned long& ul)
{
	return BasicToString(ul); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const unsigned long long& ul)
{
	return BasicToString(ul); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const char& c)
{
	return BasicToString(c); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const unsigned char& uc)
{
	return BasicToString(uc); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const short& sh)
{
	return BasicToString(sh); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const unsigned short& ush)
{
	return BasicToString(ush); // TODO: Add formatting capability
}

inline std::string Convert(const std::string& fmt, const long double& d) // fmt contains the number of digits of precision after the decimal point or a 'C' for currency
{
	std::stringstream ss;
	if (fmt.empty())
	{
		return BasicToString(d);
	}
	else if (fmt[0] == 'C') // process it as currency
	{
		ss << "$"; // TODO: get the actual localized currency symbol
		ss.precision(2); // TODO: Get the actual localized number of digits to print after the decimal point
		ss << std::fixed << d;
		return ss.str();
	}
	else
	{
		int len = boost::lexical_cast<int>(fmt);
		ss.precision(len);
		ss << std::fixed << d;
		return ss.str();
	}
}

inline std::string Convert(const std::string& fmt, const double& d) // fmt contains the number of digits of precision after the decimal point
{
	std::stringstream ss;
	if (fmt.empty())
	{
		return BasicToString(d);
	}
	else if (fmt[0] == 'C') // process it as currency
	{
		ss << "$"; // TODO: get the actual localized currency symbol
		ss.precision(2); // TODO: Get the actual localized number of digits to print after the decimal point
		ss << std::fixed << d;
		return ss.str();
	}
	else
	{
		int len = boost::lexical_cast<int>(fmt);
		ss.precision(len);
		ss << std::fixed << d;
		return ss.str();
	}
}

inline std::string Convert(const std::string& fmt, const float& f) // fmt contains the number of digits of precision after the decimal point
{
	std::stringstream ss;
	if (fmt.empty())
	{
		return BasicToString(f);
	}
	else if (fmt[0] == 'C') // process it as currency
	{
		ss << "$"; // TODO: get the actual localized currency symbol
		ss.precision(2); // TODO: Get the actual localized number of digits to print after the decimal point
		ss << std::fixed << f;
		return ss.str();
	}
	else
	{
		int len = boost::lexical_cast<int>(fmt);
		ss.precision(len);
		ss << std::fixed << f;
		return ss.str();
	}
}

inline std::string Convert(const std::string& fmt, const std::string& s) // fmt contains the minimum width to display, right aligned, padded with spaces
{
	if (fmt.empty())
		return BasicToString(s);

	size_t len = 0;
	try
	{
		len = boost::lexical_cast<int>(fmt);
	}
	catch (boost::bad_lexical_cast& ex)
	{
		throw std::invalid_argument("Invalid format string.  The format string must contain only digits.");
	}
	if (s.length() <= len)
	{
		std::stringstream ss;
		ss.width(len);
		ss.fill(' ');
		ss << s;
		return ss.str();
	}
	else
		return s;
}

inline std::string Convert(const std::string& fmt, const char* cp)
{
	std::string s(cp);
	return Convert(fmt, s);
}

template<typename T>
std::string GetArgByIndex(const std::string& argFmt, int index, T& t)
{
	if (index)
		throw std::invalid_argument("The argument index was out of range.");
	else
		return Convert(argFmt, t);
}

template<typename T, typename ... Args>
std::string GetArgByIndex(const std::string& argFmt, int index, T& t, Args ... args)
{
	if (index)
		return GetArgByIndex(argFmt, index - 1, args...);
	else
		return Convert(argFmt, t);
}

template<typename ... Args>
std::string StrFormat(const std::string& fmt, Args ... args)
{
	std::string outString;

	for (auto it = fmt.begin(); it != fmt.end(); ++it)
	{
		if (*it == '{')
		{
			// it's possibly the start of an argument
			++it;
			std::string argNum, argFmt;
			if (*it == '{')
				// not an argument, just append the literal '{' character
				outString += *it;
			else
			{
				// process it as an argument string
				bool isFmtStr = false;
				while (*it != '}')
				{
					switch (*it)
					{
						case ':': // the colon indicates the beginning of the format string for this argument
						{
							if (isFmtStr)
								argFmt += *it; // include the colon in the format string.  it may be used at a later date
							else
								isFmtStr = true;
							break;
						}
						case '0':
						case '1':
						case '2':
						case '3':
						case '4':
						case '5':
						case '6':
						case '7':
						case '8':
						case '9':
						{
							if (isFmtStr)
								argFmt += *it;
							else
								argNum += *it;
							break;
						}
						default:
						{
							if (isFmtStr)
								argFmt += *it;
							else
								throw std::invalid_argument("Argument index must be an integer.");
							break;
						}
					}
					++it;
				}
				size_t index = 0;

				if (argNum.empty())
					throw std::invalid_argument("Empty argument index.");

				try
				{
					index = boost::lexical_cast<size_t>(argNum);
				}
				catch (boost::bad_lexical_cast& ex)
				{
					throw std::invalid_argument("Argument index must be an integer.");
				}

				outString += GetArgByIndex(argFmt, index, args...);
			}
		}
		else
			// not an argument, just append the literal character
			outString += *it;
	}
	return outString;
}

inline std::string StrFormat(const std::string& fmt = "")
{
	return fmt;
}