I’m implementing a stream insertion operator for a class of mine. I’d like my class to work with both narrow and wide streams. I’m using a template to allow this kind of behavior — and everything is independent of which stream type is actually used, with the exception of character literals. If it’s a wide string, the character literals need L prepended to the literal, otherwise they do not.
Is there a way to key this sort of thing to the template parameter so that I don’t need to duplicate so much code on this?
(I would prefer to avoid performing narrow-to-wide character or wide-to-narrow character conversions at runtime if possible.)
Example of what I currently have — it’s a template but it won’t work with narrow character streams because of the wide character literals:
template <typename charT, typename traits>
std::basic_ostream<charT, traits>& operator<<(
std::basic_ostream<charT, traits>& lhs,
const Process& rhs
)
{
lhs << L"Process (0x" << std::setw(8) << std::hex
<< std::setfill(L'0') << rhs.GetId() << L") ";
lhs << rhs.GetName() << std::endl;
lhs << L"Command Line: " << 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 << L" --> " << *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 << L" --> " << it->second << std::endl;
}
return lhs;
}
If you don’t want the runtime overhead, I think that, although ugly, a macro can help you in this case.
You can probably expand
doselectwith another nice macro, to further reduce code duplication. i.e.doselect2(" --> ")would automatically expand todoselect(charT, " --> ").