String representation of a type

S

Scott Meyers

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
 
J

Johannes Schaub (litb)

Scott said:
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/
 
S

Scott Meyers


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
 
M

Marc

Scott said:
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" ;-)
 
M

Marc

Scott said:
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...
 
S

Scott Meyers

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
 
M

Miles Bader

Marc said:
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
 
M

Marc

Miles said:
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.
 
M

Marc

Marc said:
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.
 
N

Noah Roberts

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
 
M

Marc

Scott said:
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."
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

vector representation 6
type_name? no! 6
Incomplete array type 2
Reference Type 22
Type of template member functions. 9
Representation of Pointer-to-Struct 17
Type of a string literal 13
Type name as string 5

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top