I want to output my own object to a STL stream but with customized formatting. I came up with something like this but since I never used locale and imbue before I have no idea if this makes sense and how to implement MyFacet and operator<<.
So my questions are: does this make sense and how to implement MyFacet and operator<< ?
The following is a simplified example which shows you what I want to do.
struct MyObject
{
int i;
std::string s;
};
std::ostream &operator<<(std::ostream &os, const MyObject &obj)
{
if (????)
{
os << obj.i;
}
else
{
os << obj.s;
}
}
MyObject o;
o.i = 1;
o.s = "hello";
std::cout.imbue(locale("", new MyFacet(MyFacet::UseInt)));
std::cout << o << std::endl; // prints "1"
std::cout.imbue(locale("", new MyFacet(MyFacet::UseString)));
std::cout << o << std::endl; // prints "hello"
Implementing your own operator << for tracing is generally a good idea. However I've never needed to imbue locales. However I tried it and it worked fine. Here's what I did:
class my_facet : public std::locale::facet
{
public:
enum option{
use_string,
use_numeric
};
//Unique id for facet family, no locale can contain two
//facets with same id.
static std::locale::id id;
my_facet(option o=use_numeric):
facet(0),
_option(o)
{//Initialize reference count to zero so that the memory
//management will be handled by locale
};
option get_option() const {return _option;};
protected:
option _option;
};
std::locale::id my_facet::id(123456); //Facet family unique id
std::ostream& operator<<(std::ostream& os, const myobj& o)
{
std::locale const& l = os.getloc();
if( std::has_facet<my_facet>(l) ){
my_facet const& f = std::use_facet<my_facet>(l);
switch(f.get_option()){
case my_facet::use_numeric:
os << "Using numeric! ";
break;
case my_facet::use_string:
os << "Using string! ";
break;
default:
os << "Unhandled case.. ";
break;
}
return os;
}
os << "Default case when no facet has been set";
return os;
}
Then to imbue a locale with the facet:
std::locale mylocale(locale("US"), new my_facet(my_facet::use_numeric));
std::cout.imbue(mylocale);
However a more elegant way would be to implement different facets of the same facet family that can be replaced in the locale.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With