2009-07-08 8 views
3

Ich möchte mein eigenes Objekt in einem STL-Stream aber mit angepasster Formatierung ausgeben. Ich habe mir so etwas ausgedacht, aber da ich nie das Gebietsschema benutzt habe und erst dann habe ich keine Ahnung, ob das sinnvoll ist und wie man MyFacet und den Operator < < implementiert.Wie formatiere ich meine eigenen Objekte bei der Verwendung von STL-Streams?

Also meine Fragen sind: macht das Sinn und wie MyFacet und Operator < < zu implementieren?

Das folgende ist ein vereinfachtes Beispiel, das Ihnen zeigt, was ich tun möchte.

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" 

Antwort

1

Nun wird ein locale allgemein verwendet, um verschiedenen Ausgang/Eingang des gleichen Objekts ermöglichen Formatierung auf der Grundlage der lokalen (die angegebenen locale in der Tat), die Formatierung vorhanden ist. Für einen guten Artikel hierzu siehe: http://www.cantrip.org/locale.html. Vielleicht liegt es daran, dass das obige Beispiel ziemlich vereinfacht ist, aber für mich sieht es so aus, als ob Sie versuchen würden, auf clevere Weise zwischen dem Drucken eines Teils eines Objekts oder eines anderen zu wechseln. Wenn dies der Fall ist, kann es einfacher sein, den Stream-Operator für jeden Typ einfach zu überladen und den if-Schalter extern zu verwenden.

Wie auch immer, ich werde nicht behaupten, dass ich ein Experte in Facetten und Schauplätzen bin, sondern einen Blick auf diesen Artikel werfen, der ziemlich gründlich ist und Ihnen eine bessere Erklärung geben wird als ich!

+0

Ich stimme zu, ein externer Schalter wäre einfacher und das ist, was ich zuerst kam. Aber dann brauchte ich auch eine Datumsformatierung, die vom Gebietsschema abhängt, und dann dachte ich, warum sollte man nicht dieselbe Methode für alles verwenden, um sie konsistent zu halten. Da ich aber STL und locales nicht zu gut kenne, war meine Frage auch, ob es Sinn macht oder nicht;) – rve

+0

Danke für den Link, es erklärt wirklich, wie ich das umsetzen könnte. Jetzt muss ich noch entscheiden, ob ich das Gebietsschema dafür "missbrauchen" soll oder nicht ... – rve

4

Implementieren Sie Ihren eigenen Operator < < für die Verfolgung ist in der Regel eine gute Idee. Ich musste jedoch nie Gebietsschemas hinzufügen. Aber ich habe es versucht und es hat gut funktioniert. Hier ist, was ich getan habe:

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; 
} 

Dann ein Gebietsschema mit der Facette zu verleihen:

std::locale mylocale(locale("US"), new my_facet(my_facet::use_numeric)); 
std::cout.imbue(mylocale); 

jedoch eine elegantere Möglichkeit wäre es, unterschiedliche Facetten derselben Facette Familie zu implementieren, die in der ersetzt werden kann Gebietsschema.