Templateparameter zu String



  • Danke für deine Mühe 🙂 Habs auch gerade eben doch noch selbst gefunden



  • typeid(T).name() ist übrigens compilerabhängig.
    während VC++ da schöne Namen wie "int", "class std::string" usw. fabriziert,
    kommt da beim GCC zum Beispiel "i" (int) oder "Ss" (S = std::, s = string) raus.



  • Mist das hab ich jetzt gar nicht mehr getestet, hast du einen ähnlichnen, alternativen Vorschlag für den GCC?

    Gruß 🙂



  • MatheStein schrieb:

    ... hast du einen ähnlichen, alternativen Vorschlag für den GCC?

    im schlimmsten Fall -> selbst ist der Mann!
    heißt z.B.:

    template< typename T >
    struct TypeName // Default Implementierung
    {
        static const char* Name() { return typeid(T).name(); }
    };
    #define TYPENAME( t, x ) template<> struct TypeName< t > { \
        static const char* Name() { return (x); } }
    
    // --   hier bitte ausfüllen
    TYPENAME( int, "ein int" );
    TYPENAME( double, "Fliesskomma" );
    struct Foo;
    TYPENAME( Foo, "meine tolle Klasse" );
    // usw. ...
    
    template< typename T >
    void foo()
    {
        std::cout << TypeName< T >::Name() << std::endl;
    }
    

    Gruß
    Werner



  • Habe hier auch gerade etwas gefunden:

    abi::__cxa_demangle(typeid(int).name(), 0, 0, &status)
    

    Offensichtlich kann man hier mit die internen Namen des GCC in "sinnvollere" umwandeln, lese mich aber gerde selbst erst ein. Scheint aber zu klappen 🙂



  • MatheStein schrieb:

    Habe hier auch gerade etwas gefunden:

    abi::__cxa_demangle(typeid(int).name(), 0, 0, &status)
    

    Offensichtlich kann man hier mit die internen Namen des GCC in "sinnvollere" umwandeln, lese mich aber gerde selbst erst ein. Scheint aber zu klappen 🙂

    Das ist allerdings wiederum GCC Abhängig.
    Wofür brauchst du das überhaupt?



  • Ist eine etwas fiesere Geschichte..

    Baue eine Art Interpreter der irgendwelche Codefragmente als String verarbeitet und an einer Stelle brauche ich von einem Templateparameter den Datentyp als String um vernünftigen Code generieren zu können.. Ungefähr so etwas in der Art

    Gruß 🙂



  • Eh.. ja, das hört sich nach Quatsch an.



  • MatheStein schrieb:

    Habe hier auch gerade etwas gefunden:

    abi::__cxa_demangle(typeid(int).name(), 0, 0, &status)
    

    Offensichtlich kann man hier mit die internen Namen des GCC in "sinnvollere" umwandeln, lese mich aber gerde selbst erst ein. Scheint aber zu klappen 🙂

    Nicht vergessen: Der Pointer, der da zurückgegeben wird, muss selber wieder freigegeben werden!



  • Danke 🙂

    Ist der Rückgabewert ein C-String, also macht man das ca so:

    char* s = abi::__cxa_demangle(typeid(int).name(), 0, 0, &status);
    
    // ...
    
    free(s);
    

    Oder macht man das mit "delete" ?

    Gruß



  • MatheStein schrieb:

    Oder macht man das mit "delete" ?

    Nein - mit free (siehe http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html).

    Besser als es selber später mit free freizugeben, ist die Verwendung von RAII im Allgemeinen und Smart-Pointer im Besonderen

    std::shared_ptr< char > s( abi::__cxa_demangle(typeid(int).name(), 0, 0, &status), &::free ); // erfordert #include <memory> und C++11
    

    danach brauchst Du Dich um das Freigeben nicht mehr zu kümmern.

    Gruß
    Werner



  • Hmm, bevor ich für soetwas den Overhead eines shared_ptr in Kauf nehmen würde, würde ich eher an free denken. 😉

    char* demangled = abi::__cxa_demangle(typeid(int).name(), 0, 0, &status);
    std::string s(demangled);
    free(demangled);
    

    Ja ... der Konstruktor von s kann bad_alloc werfen, sowas ist aber vermutlich in der Geschichte noch nie passiert, wenn es um Speicher für max. 15 Bytes geht. 😉



  • Ethon schrieb:

    Hmm, bevor ich für soetwas den Overhead eines shared_ptr in Kauf nehmen würde, würde ich eher an free denken. 😉

    Ne, das ist nicht mal exception safe. Und der "overhead" von shared_ptr dürfte hier auch kaum spürbar sein, aber unique_ptr wäre natürlich trotzdem angebrachter.



  • cooky451 schrieb:

    Ethon schrieb:

    Hmm, bevor ich für soetwas den Overhead eines shared_ptr in Kauf nehmen würde, würde ich eher an free denken. 😉

    Ne, das ist nicht mal exception safe. Und der "overhead" von shared_ptr dürfte hier auch kaum spürbar sein, aber unique_ptr wäre natürlich trotzdem angebrachter.

    ich wusste zunächst nicht, dass std::unique_ptr das kann. Man kann tatsächlich einen Deleter als zweiten Parameter angeben, aber so einfach wie beim shared_ptr geht es nicht (compiliert nicht mit VC10)!

    Wer weiß, was man hier tun muss, um std::unique_ptr zu benutzen?



  • unique_ptr will den deleter mit im Typen haben:

    std::unique_ptr<char, decltype(&std::free)> p(.., &std::free);
    

Anmelden zum Antworten