Re: "Type-safe" sprintf
 
This is a multi-part message in MIME format.
------=_NextPart_000_0221_01C761C4.9EFEEE20
Content-Type: text/plain;
    charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Try this instead (much cleaner - see examples below):
#include <string>
#include <sstream>
#include <tchar.h>
// TCHAR versions of "std::string", etc.
typedef std::basic_string<TCHAR> tstring;
typedef std::basic_ostringstream<TCHAR> tostringstream;
/////////////////////////////////////////////////////////////////////////=
////
// "FormatStr" class. Use this class to format a "tstring" on the fly =
with
// streaming arguments. It's basically the C++ answer to "sprintf()" =
style
// argument lists. Instead of passing a format string and variable =
number
// of arguments however, just construct a temporary as seen in the =
examples
// below and stream the same arguments you would normally pass to any
// "std::ostream" object via the << operator. The result can then be
// implicitly converted to a "tstring" via the "tstring()" operator so
// you can effectively use it wherever you would use a "tstring" =
(frequently
// as a "const tstring &" argument for instance - see example 2 below).
//
// Example 1
// ---------
//
//   // Results in "Bill Gates is worth 50 billion dollars"
//   tstring String = FormatStr() << _T("Bill Gates is worth ") << 50 =
<< _T(" billion dollars");
//
// Example 2 (as above but pass to a function on the fly)
// ---------
//
//   void YourFunc(const tstring &String)
//   {
//       // ...
//   }
//
//   YourFunc(FormatStr() << _T("Bill Gates is worth ") << 50 << _T(" =
billion dollars");
//
/////////////////////////////////////////////////////////////////////////=
////
class FormatStr
{
public:
    ////////////////////////////////////////////
    // IMPORTANT: Don't make T a reference arg
    // under VC6 (unfortunately). Some later
    // versions of VC6 have a bug and will
    // choke on it (infamous "internal compiler"
    // error).
    ////////////////////////////////////////////
    template <typename T>
    FormatStr &operator<<(const T &Whatever)
    {
        m_Stream << Whatever;
        return *this;
    }
    operator tstring() const
    {
        return m_Stream.str();
    }
private:
    tostringstream m_Stream;
};
------=_NextPart_000_0221_01C761C4.9EFEEE20
Content-Type: text/html;
    charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; =
charset=iso-8859-1">
<META content="MSHTML 6.00.2900.3059" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face="Courier New" size=2>Try this instead =
(much cleaner - see 
examples below):</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>#include =
<string><BR>#include 
<sstream><BR>#include <tchar.h></FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>// TCHAR versions of =
"std::string", 
etc.<BR>typedef std::basic_string<TCHAR> tstring;<BR>typedef 
std::basic_ostringstream<TCHAR> tostringstream;</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" 
size=2>////////////////////////////////////////////////////////////////=
/////////////<BR>// 
"FormatStr" class. Use this class to format a "tstring" on the fly =
with<BR>// 
streaming arguments. It's basically the C++ answer to "sprintf()" =
style<BR>// 
argument lists. Instead of passing a format string and variable =
number<BR>// of 
arguments however, just construct a temporary as seen in the =
examples<BR>// 
below and stream the same arguments you would normally pass to any<BR>// =
"std::ostream" object via the << operator. The result can then =
be<BR>// 
implicitly converted to a "tstring" via the "tstring()" operator =
so<BR>// you 
can effectively use it wherever you would use a "tstring" =
(frequently<BR>// as a 
"const tstring &" argument for instance - see example 2 =
below).<BR>//<BR>// 
Example 1<BR>// ---------<BR>//<BR>//   // Results in "Bill =
Gates is 
worth 50 billion dollars"<BR>//   tstring String = =
FormatStr() 
<< _T("Bill Gates is worth ") << 50 << _T(" billion 
dollars");<BR>//<BR>// Example 2 (as above but pass to a function on the =
fly)<BR>// ---------<BR>//<BR>//   void YourFunc(const tstring =
&String)<BR>//   =
{<BR>//       // 
....<BR>//   }<BR>//<BR>//   YourFunc(FormatStr() =
<< 
_T("Bill Gates is worth ") << 50 << _T(" billion 
dollars");<BR>//<BR>/////////////////////////////////////////////////////=
////////////////////////<BR>class 
FormatStr<BR>{<BR>public:<BR>    
////////////////////////////////////////////<BR>    // =
IMPORTANT: 
Don't make T a reference arg<BR>    // under VC6 =
(unfortunately). 
Some later<BR>    // versions of VC6 have a bug and 
will<BR>    // choke on it (infamous "internal 
compiler"<BR>    // error).<BR>    
////////////////////////////////////////////<BR>    =
template 
<typename T><BR>    FormatStr =
&operator<<(const T 
&Whatever)<BR>    
{<BR>        m_Stream << 
Whatever;<BR>        return 
*this;<BR>    }</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>    operator =
tstring() 
const<BR>    =
{<BR>        
return m_Stream.str();<BR>    }</FONT></DIV>
<DIV><FONT face="Courier New" size=2></FONT> </DIV>
<DIV><FONT face="Courier New" size=2>private:<BR>    
tostringstream m_Stream;<BR>};</FONT></DIV></BODY></HTML>
------=_NextPart_000_0221_01C761C4.9EFEEE20--