NEW: Thank you everyone who helped me with this! The answer is marked below, and I\'ve expanded on the answer with a functioning version in my question, below (q.v.):
The concept is to use a macro to generate both forms of the literal, char and wchar_t, then let a template function choose which one is appropriate for the context.
Remember that template functions don't actually generate any code until you have other code that makes a call to them. Most of the time this doesn't matter, but it would for a library.
This code is untested, but I believe it will work.
#define LITERAL(T,x) CString_traits::choose(x, L##x)
template
struct CString_traits
{
typedef char char_type;
static const char * choose(const char * narrow, const wchar_t * wide) { return narrow; }
static char choose(char narrow, wchar_t wide) { return narrow; }
};
template<>
struct CString_traits
{
typedef wchar_t char_type;
static const wchar_t * choose(const char * narrow, const wchar_t * wide) { return wide; }
static wchar_t choose(char narrow, wchar_t wide) { return wide; }
};
template
inline void MakeQuoted(T & str, CString_traits::char_type chQuote = LITERAL(T,'"'))
{
if (str.IsEmpty() || str[0] != chQuote)
str.Format(LITERAL(T,"%c%s%c"), chQuote, str, chQuote);
}