Что я делаю, так это вставляю только символ и преобразую их в широкий или узкий символ.Преобразование выполняется во время компиляции, и если вы используете только символы, которые равны в широкой и узкой кодировке, это работает.Это утомительно, но работает.
template <typename charT, typename traits>
std::basic_ostream<charT, traits>& operator<<(
std::basic_ostream<charT, traits>& lhs,
const Process& rhs
)
{
lhs << charT('P') << charT('r') << charT('o') << charT('c') << charT('e')
<< charT('s') << charT('s') << charT(' ') << charT('(') << charT('0')
<< charT('x') << std::setw(8) << std::hex << std::setfill(charT('0'))
<< rhs.GetId() << charT(')') << charT(' ');
lhs << rhs.GetName() << std::endl;
lhs << charT('C') << charT('o') << charT('m') << charT('m') << charT('a')
<< charT('n') << charT('d') << charT(' ') << charT('L') << charT('i')
<< charT('n') << charT('e') << charT(':') << charT(' ')
<< rhs.GetCmdLine() << std::endl;
const std::vector<Thread>& threads = rhs.GetThreads();
for (std::vector<Thread>::const_iterator it = threads.begin();
it != threads.end(); ++it)
{
lhs << charT(' ') << charT('-') << charT('-') << charT('>') << charT(' ')
<< *it << std::endl;
}
const std::map<void *, Module>& modules = rhs.GetModules();
for (std::map<void *, Module>::const_iterator it = modules.begin();
it != modules.end(); ++it)
{
lhs << charT(' ') << charT('-') << charT('-') << charT('>') << charT(' ')
<< it->second << std::endl;
}
return lhs;
}
Если у вас много строк, вы можете использовать другой шаблон, который вы будете специализировать на широком или узком типе символов и использовать для хранения строк.Это, однако, заставит вас продублировать ваши строки (и вы нарушите принцип СУХОГО).
template <typename charT>
struct ProcessInsertionOperatorHelper
{
static const charT* const String1;
static const charT* const String2;
static const charT* const String3;
static const charT* const String4;
};
template <>
const wchar_t* const ProcessInsertionOperatorHelper<wchar_t>::String1 = L"Process (0x";
template <>
const wchar_t* const ProcessInsertionOperatorHelper<wchar_t>::String2 = L") ";
template <>
const wchar_t* const ProcessInsertionOperatorHelper<wchar_t>::String3 = L"Command Line: ";
template <>
const wchar_t* const ProcessInsertionOperatorHelper<wchar_t>::String4 = L" --> ";
template <>
struct ProcessInsertionOperatorHelper<char>
{
};
template <typename charT, typename traits>
std::basic_ostream<charT, traits>& operator<<(
std::basic_ostream<charT, traits>& lhs,
const Process& rhs
)
{
lhs << ProcessInsertionOperatorHelper<charT>::String1 << std::setw(8)
<< std::hex << std::setfill(L'0') << rhs.GetId()
<< ProcessInsertionOperatorHelper<charT>::String2;
lhs << rhs.GetName() << std::endl;
lhs << ProcessInsertionOperatorHelper<charT>::String3
<< rhs.GetCmdLine() << std::endl;
const std::vector<Thread>& threads = rhs.GetThreads();
for (std::vector<Thread>::const_iterator it = threads.begin();
it != threads.end(); ++it)
{
lhs << ProcessInsertionOperatorHelper<charT>::String4
<< *it << std::endl;
}
const std::map<void *, Module>& modules = rhs.GetModules();
for (std::map<void *, Module>::const_iterator it = modules.begin();
it != modules.end(); ++it)
{
lhs << ProcessInsertionOperatorHelper<charT>::String4
<< it->second << std::endl;
}
return lhs;
}