You may take advantage of overloading by the first argument.
//For human-readable output
std::ostream& operator<< (std::ostream& os, my_enum e);
//For database; note the absence VVV of & sign here
std::ostream& operator<< (databasefmt fmt, my_enum e)
{
std::ostream& os = fmt.stream;
// Write data to os
// ...
return os;
}
struct databasefmt{
std::ostream& stream;
databasefmt(std::ostream & s) : stream(s) {};
};
Then write stream modifier that converts the stream to wrapping databasefmt class, so that next output to that modified stream would be database output for you enum. The printing code would look like this:
output_stream << "DATA: "<< database_format << my_enum::Value << "END OF DATA" ;
// Type: std::ostream | databasefmt | std::ostream |
and the wrapper like this:
//Variable is needed to avoid confusing parentheses in output operators
struct databasefmt_converter_t {} database_format;
// we can't return reference, so we just return fairly small instance of wrapper
databasefmt operator<< (std::ostream& os, databasefmt_converter_t const&)
{ return databasefmt(os); }