Re: string selection.
I have a general question. When you guys want to use a string class in
Visual C++, would you use std::string in stl library or CStringT in atl
library.
Both of them can accomplish my task, I just want to hear what's your
preference.
It depends on various factors but it often boils down to a religious issue.
I would personally stick with "std::string" but typedef'd as follows under
Windows:
typedef std::basic_string<TCHAR> tstring;
It's cleaner and more generic IMO. If you're using another string such as
"CStringT" in the same code because some API requires it for instance (where
it's more convenient and syntactically cleaner than converting
"std::string"), then you may want to choose that instead since you'll end up
with two string types otherwise (not good). In any case, I like formatting
C++ strings using the following technique:
#include <string>
#include <sstream>
#include <tchar.h>
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
// in 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;
};