String representation of a type

Discussion in 'C++' started by Scott Meyers, Jan 29, 2011.

  1. Scott Meyers

    Scott Meyers Guest

    The draft C++0x standard tells me (in 7.1.6.2/4) the following:

    const int&& foo();
    int i;
    decltype(foo()) x1 = i; // type is const int&&

    Suppose I'd like to verify that decltype(foo()) really returns the type
    const int&&. How can I do that? If I apply typeid and then print the
    type's name,

    std::string s = typeid(decltype(foo())).name();
    std::cout << s << '\n';

    VC10 prints "int" and gcc 4.5 prints "i". Both are standard-conforming,
    because std::typeinfo::name can return whatever it wants, but neither
    helps me confirm that decltype returns what the draft standard says it
    should.

    In their book, "C++ Template Metaprogramming," David Abrahams and
    Aleksey Gurtovoy recommend the following approach, which they say will
    cause a diagnostic to be issued showing the type:

    template<typename T> struct incomplete;

    incomplete<decltype(foo())> x;

    This works as advertised, yielding

    types.cpp(51) : error C2079: 'x' uses undefined class 'incomplete<T>'
    with
    [
    T=const int &&
    ]

    on VC10 and

    types.cpp:51:33: error: aggregate 'incomplete<const int &&> x' has
    incomplete type and cannot be defined

    with gcc 4.5. But I'd really like to have a lexical representation of
    the type in a std::string at runtime, so the compile-time-diagnostic
    trick is not what I'm looking for.

    Using type traits and/or overloading, I could write the code to generate
    a string representation of a type, but dealing with all the
    possibilities (e.g., function types, member pointer types, pointers to
    pointers to pointers..., const and/or volatile qualifiers, etc.) would
    be, er, time-consuming. I'm hoping that somebody has already consumed
    that time and shared their work with the world. Is there some code
    floating around somewhere that takes a type and returns a string
    representation of that type, i.e., something that would let me write
    something like

    std::string s = Type<decltype(foo())>().name();
    std::cout s; // prints something like "const int &&"

    Thanks,

    Scott
     
    Scott Meyers, Jan 29, 2011
    #1
    1. Advertising

  2. Scott Meyers wrote:

    > The draft C++0x standard tells me (in 7.1.6.2/4) the following:
    >
    > const int&& foo();
    > int i;
    > decltype(foo()) x1 = i; // type is const int&&
    >
    > Suppose I'd like to verify that decltype(foo()) really returns the type
    > const int&&. How can I do that? If I apply typeid and then print the
    > type's name,
    >
    > std::string s = typeid(decltype(foo())).name();
    > std::cout << s << '\n';
    >
    > VC10 prints "int" and gcc 4.5 prints "i". Both are standard-conforming,
    > because std::typeinfo::name can return whatever it wants, but neither
    > helps me confirm that decltype returns what the draft standard says it
    > should.
    >
    > In their book, "C++ Template Metaprogramming," David Abrahams and
    > Aleksey Gurtovoy recommend the following approach, which they say will
    > cause a diagnostic to be issued showing the type:
    >
    > template<typename T> struct incomplete;
    >
    > incomplete<decltype(foo())> x;
    >
    > This works as advertised, yielding
    >
    > types.cpp(51) : error C2079: 'x' uses undefined class 'incomplete<T>'
    > with
    > [
    > T=const int &&
    > ]
    >
    > on VC10 and
    >
    > types.cpp:51:33: error: aggregate 'incomplete<const int &&> x' has
    > incomplete type and cannot be defined
    >
    > with gcc 4.5. But I'd really like to have a lexical representation of
    > the type in a std::string at runtime, so the compile-time-diagnostic
    > trick is not what I'm looking for.
    >
    > Using type traits and/or overloading, I could write the code to generate
    > a string representation of a type, but dealing with all the
    > possibilities (e.g., function types, member pointer types, pointers to
    > pointers to pointers..., const and/or volatile qualifiers, etc.) would
    > be, er, time-consuming. I'm hoping that somebody has already consumed
    > that time and shared their work with the world. Is there some code
    > floating around somewhere that takes a type and returns a string
    > representation of that type, i.e., something that would let me write
    > something like
    >
    > std::string s = Type<decltype(foo())>().name();
    > std::cout s; // prints something like "const int &&"
    >


    Someone already did that. See
    https://github.com/Eelis/geordi/blob/master/prelude/type_strings.hpp . Help
    is at http://www.xs4all.nl/~weegen/eelis/geordi/
     
    Johannes Schaub (litb), Jan 29, 2011
    #2
    1. Advertising

  3. Scott Meyers

    Scott Meyers Guest

    On 1/28/2011 8:57 PM, Johannes Schaub (litb) wrote:
    > Someone already did that. See
    > https://github.com/Eelis/geordi/blob/master/prelude/type_strings.hpp . Help
    > is at http://www.xs4all.nl/~weegen/eelis/geordi/


    I downloaded the source code and tried to find a way to use this
    facility as part of a native C++ application, but it doesn't seem to be
    designed to be used this way: it appears to be designed only to work on
    Unix-like systems under gcc. Has anybody already ported this to
    Windows? (gcc is fine, but it'd be nice if it ran under both gcc and
    VC.) Or is there some other facility that will do what I want under
    Windows?

    Thanks,

    Scott
     
    Scott Meyers, Jan 31, 2011
    #3
  4. Scott Meyers

    Marc Guest

    Scott Meyers wrote:

    > The draft C++0x standard tells me (in 7.1.6.2/4) the following:
    >
    > const int&& foo();
    > int i;
    > decltype(foo()) x1 = i; // type is const int&&
    >
    > Suppose I'd like to verify that decltype(foo()) really returns the type
    > const int&&. How can I do that? If I apply typeid and then print the
    > type's name,
    >
    > std::string s = typeid(decltype(foo())).name();
    > std::cout << s << '\n';
    >
    > VC10 prints "int" and gcc 4.5 prints "i". Both are standard-conforming,
    > because std::typeinfo::name can return whatever it wants, but neither
    > helps me confirm that decltype returns what the draft standard says it
    > should.


    They seem to ignore cvref qualifiers on the main type, but:
    template<class>struct Dummy{};
    typeid(Dummy<decltype(...)>).name() contains the information, with a
    little noise on the side. Same for typeid(void(decltype(...))).name()
    I guess, or anything that moves the cvref inside the type.

    > In their book, "C++ Template Metaprogramming," David Abrahams and
    > Aleksey Gurtovoy recommend the following approach, which they say will
    > cause a diagnostic to be issued showing the type:
    >
    > template<typename T> struct incomplete;
    >
    > incomplete<decltype(foo())> x;


    Yes, and it gives you the demangling for free :)

    > Using type traits and/or overloading, I could write the code to generate
    > a string representation of a type, but dealing with all the
    > possibilities (e.g., function types, member pointer types, pointers to
    > pointers to pointers..., const and/or volatile qualifiers, etc.) would
    > be, er, time-consuming.


    Sounds like a nice "exercice for the reader" ;-)
     
    Marc, Jan 31, 2011
    #4
  5. Scott Meyers

    Marc Guest

    Marc wrote:

    >> Using type traits and/or overloading, I could write the code to generate
    >> a string representation of a type, but dealing with all the
    >> possibilities (e.g., function types, member pointer types, pointers to
    >> pointers to pointers..., const and/or volatile qualifiers, etc.) would
    >> be, er, time-consuming.

    >
    > Sounds like a nice "exercice for the reader" ;-)


    Like:
    http://geometrica.saclay.inria.fr/team/Marc.Glisse/tmp/printtype.cpp
     
    Marc, Jan 31, 2011
    #5
  6. Scott Meyers

    Scott Meyers Guest

    Scott Meyers, Feb 1, 2011
    #6
  7. Scott Meyers

    Marc Guest

    Marc, Feb 1, 2011
    #7
  8. Scott Meyers

    Scott Meyers Guest

    On 2/1/2011 4:07 AM, Marc wrote:
    > Yes, looked like fun. I probably missed a few corner cases though, and
    > the code could do with some cleanup...


    Still, very impressive. And thanks!

    Scott
     
    Scott Meyers, Feb 1, 2011
    #8
  9. Scott Meyers

    Miles Bader Guest

    Marc <> writes:
    >>> Like:
    >>> http://geometrica.saclay.inria.fr/team/Marc.Glisse/tmp/printtype.cpp

    >>
    >> Very sweet! Did you just whip this up on the spur of the moment?

    >
    > Yes, looked like fun. I probably missed a few corner cases though, and
    > the code could do with some cleanup...


    Of course it depends on the system's type_info::name method to return
    the names of class types, which it doesn't in gcc; in gcc,
    type_info::name returns the mangled type name, so your proggie yields:

    5Perso
    unsigned long* const* volatile*&()
    void(*&)(int(*)(),5Perso&)
    5Perso const&(...)
    long double(int volatile*,...)
    int(5Perso::**)(double)
    short const volatile 5Perso::*
    int(*(*(&)(long))(char))(double)

    I guess that could be worked-around by just skipping any digits at the
    beginning of the class name, which obviously aren't a valid part of the
    name...

    -Miles

    --
    /\ /\
    (^.^)
    (")")
    *This is the cute kitty virus, please copy this into your sig so it can spread.
     
    Miles Bader, Feb 2, 2011
    #9
  10. Scott Meyers

    Marc Guest

    Miles Bader wrote:

    > Marc <> writes:
    >>>> http://geometrica.saclay.inria.fr/team/Marc.Glisse/tmp/printtype.cpp

    >
    > Of course it depends on the system's type_info::name method to return
    > the names of class types, which it doesn't in gcc; in gcc,
    > type_info::name returns the mangled type name, so your proggie yields:


    Well yes, I don't think there is much that can be done about it, so I
    used type_info::name as a default. Note that you could still register
    your own classes, templates, etc, but that's a not as nice.

    > I guess that could be worked-around by just skipping any digits at the
    > beginning of the class name, which obviously aren't a valid part of the
    > name...


    That might work for simple classes, but as soon as you add templates
    to the mix... And you can't just stick _Z in front and call c++filt to
    demangle, because sometimes you need a couple more letters in between.
     
    Marc, Feb 2, 2011
    #10
  11. Scott Meyers

    Marc Guest

    Marc wrote:

    > Scott Meyers wrote:
    >
    >> On 1/31/2011 3:35 PM, Marc wrote:
    >>> Like:
    >>> http://geometrica.saclay.inria.fr/team/Marc.Glisse/tmp/printtype.cpp

    >>
    >> Very sweet! Did you just whip this up on the spur of the moment?

    >
    > Yes, looked like fun. I probably missed a few corner cases though, and
    > the code could do with some cleanup...


    Indeed I had missed arrays. I added T[d] (works like functions, except
    that removing extra parentheses is not so nice) but am still missing
    T[]. I'll try to add it sometime.
     
    Marc, Feb 2, 2011
    #11
  12. Scott Meyers

    Noah Roberts Guest

    In article <ii0482$fqa$>,
    says...

    > Using type traits and/or overloading, I could write the code to generate
    > a string representation of a type, but dealing with all the
    > possibilities (e.g., function types, member pointer types, pointers to
    > pointers to pointers..., const and/or volatile qualifiers, etc.) would
    > be, er, time-consuming. I'm hoping that somebody has already consumed
    > that time and shared their work with the world. Is there some code
    > floating around somewhere that takes a type and returns a string
    > representation of that type, i.e., something that would let me write
    > something like
    >
    > std::string s = Type<decltype(foo())>().name();
    > std::cout s; // prints something like "const int &&"
    >
    > Thanks,
    >
    > Scott


    The C++ TMP book reserves implementing something like this as an
    exercize. You can see various solutions at the Wiki reserved for people
    to share such answers:

    http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?
    CPPTM_Answers_-_Exercise_2-3


    --
    http://crazycpp.wordpress.com/
     
    Noah Roberts, Feb 2, 2011
    #12
  13. Scott Meyers

    Marc Guest

    Scott Meyers wrote:

    > The draft C++0x standard tells me (in 7.1.6.2/4) the following:
    >
    > const int&& foo();
    > int i;
    > decltype(foo()) x1 = i; // type is const int&&
    >
    > Suppose I'd like to verify that decltype(foo()) really returns the type
    > const int&&. How can I do that? If I apply typeid and then print the
    > type's name,
    >
    > std::string s = typeid(decltype(foo())).name();
    > std::cout << s << '\n';
    >
    > VC10 prints "int" and gcc 4.5 prints "i". Both are standard-conforming,
    > because std::typeinfo::name can return whatever it wants, but neither
    > helps me confirm that decltype returns what the draft standard says it
    > should.


    I just saw on the gcc mailing-list that typeid is actually forced to
    ignore the cv-qualifiers:

    "If the type of the type-id is a reference to a possibly cv-qualified
    type, the result of the typeid expression refers to a std::type_info
    object representing the cv-unqualified referenced type."
     
    Marc, Feb 3, 2011
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hessam
    Replies:
    0
    Views:
    2,204
    Hessam
    Aug 8, 2003
  2. =?Utf-8?B?UmFqZXNoIHNvbmk=?=

    'System.String[]' from its string representation 'String[] Array'

    =?Utf-8?B?UmFqZXNoIHNvbmk=?=, May 4, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    1,821
    =?Utf-8?B?UmFqZXNoIHNvbmk=?=
    May 4, 2006
  3. Allan Ebdrup
    Replies:
    1
    Views:
    653
    Allan Ebdrup
    Jul 16, 2007
  4. Hessam
    Replies:
    1
    Views:
    250
    Teemu Keiski
    Aug 16, 2003
  5. Hessam
    Replies:
    0
    Views:
    287
    Hessam
    Aug 8, 2003
Loading...

Share This Page