unscrambling typeid().name

D

Deepak Jharodia

I'm using a templatized class in GCC based environ

template<class A, class B>
class foo {...
....} F;

Now I want to know that particular instance of this class was
instantiated with what template arguments. typeid.name() returns a
strange string with all the info but abbreviated and probably platform
specific.
How can I unscramble it and probably use it my program during runtime?

TIA
 
G

Gianni Mariani

Deepak said:
I'm using a templatized class in GCC based environ

template<class A, class B>
class foo {...
...} F;

Now I want to know that particular instance of this class was
instantiated with what template arguments. typeid.name() returns a
strange string with all the info but abbreviated and probably platform
specific.
How can I unscramble it and probably use it my program during runtime?

You don't. The format of the string is "vendor specific", meaning that
if you want portability you can't use it other than the property that
it's probably unique.

typedef std::pair<const std::type_info *, const std::type_info *> types;

How about methods on foo that give you the type_info's for A and B ?

template<class A, class B>
class foo {
virtual std::type_info& typeA() {
return typeid(A);
}
virtual std::type_info& typeB() {
return typeid(B);
}
};

Or, you can create a map of type_info of foo<A,B> to A and B if you
really need it.

Or if you need specific information about A and B you can construct some
other way of programatically getting type information of A and B
respectively.

Doing any of these will be portable but parsing the string will not be.
 
J

James Kanze

You don't. The format of the string is "vendor specific",
meaning that if you want portability you can't use it other
than the property that it's probably unique.

I wouldn't count on it for types not defined at namespace scope.
(Of course, you can't instantiate templates over such types, so
that shouldn't be a problem for the original poster.)
 
S

Salt_Peter

I'm using a templatized class in GCC based environ

template<class A, class B>
class foo {...
...} F;

Now I want to know that particular instance of this class was
instantiated with what template arguments. typeid.name() returns a
strange string with all the info but abbreviated and probably platform
specific.
How can I unscramble it and probably use it my program during runtime?

TIA

Why would you need to? State your case in simplified, compileable
code.

A template is not a class.
Say you instantiate a template with foo< int, char >. Why do you need
to know what the first injected type parameter is/was? The fact that
its an integer should be transparent to the code.

example:

template<class A, class B>
class foo
{
A a;
B b;
public:
foo() : a(), b() { }
A get() const { return a; }
};

// foo< int, char >, the following class is silently generated
// (i beleive the standard calls it template instantiation)

template<>
class foo
{
int a;
char b;
public:
foo() : a(), b() { }
int get() const { return a; }
};

Now take foo< int, char > and foo< char, int > as a theoretical case.
Each of these are unique types. There is no ambiguity between the two
types.

Now, if you come from the Java world where everything and anything is
an Object, and you are trying to mimic the same hierarchy with C++,
then prepare yourself for a reality check.
 
D

Deepak Jharodia

Why would you need to? State your case in simplified, compileable
code.

A template is not a class.
Say you instantiate a template with foo< int, char >. Why do you need
to know what the first injected type parameter is/was? The fact that
its an integer should be transparent to the code.

example:

template<class A, class B>
class foo
{
  A a;
  B b;
public:
  foo() : a(), b() { }
  A get() const { return a; }

};

// foo< int, char >, the following class is silently generated
// (i beleive the standard calls it template instantiation)

template<>
class foo
{
  int a;
  char b;
public:
  foo() : a(), b() { }
  int get() const { return a; }

};

Now take foo< int, char > and foo< char, int > as a theoretical case.
Each of these are unique types. There is no ambiguity between the two
types.

Now, if you come from the Java world where everything and anything is
an Object, and you are trying  to mimic the same hierarchy with C++,
then prepare yourself for a reality check.

Oh I forgot to mention that I'm not the owner of the class in that, I
can not change it in anyway.

What I really want to know is that whether a specific pointer to the
mentioned class(say A) is inherited from a specific class(say B, which
is also templatized).
Now I try to do a dynamic_cast on the pointer for this, but for that I
need to know what template arguments were used while allocating this
pointer(of type A) because they will be same as the used for type B.

I hope I was able to make it a bit clear.
 
D

Deepak Jharodia

I wouldn't count on it for types not defined at namespace scope.
(Of course, you can't instantiate templates over such types, so
that shouldn't be a problem for the original poster.)

--
James Kanze (GABI Software)             email:[email protected]
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

So you say it will be portable(across compilers)??
I'll be using gcc(though diff versions) only on linux.
 
M

Marco Manfredini

Deepak said:
I'm using a templatized class in GCC based environ

template<class A, class B>
class foo {...
...} F;

Now I want to know that particular instance of this class was
instantiated with what template arguments. typeid.name() returns a
strange string with all the info but abbreviated and probably platform
specific.
How can I unscramble it and probably use it my program during runtime?

For recent versions of GCC, __cxa_demangle unscrambles the typename.
Please see the manual:
http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt12ch39.html
 
J

James Kanze

So you say it will be portable(across compilers)??
I'll be using gcc(though diff versions) only on linux.

You can probably count on the names being unique for all types
defined at namespace scope. The exact name for a given class
will vary from one compiler to the next, however; for a class A
in global namespace, g++ outputs "1A", Sun CC "A", and VC++
"class A", if the definition is in namespace NS, g++ outputs
"N2NS1AE", Sun CC "NS::A" and VC++ "class NS::A".

For those who are curious, I'm using the following code for test
purposes:

typeid.cc:

#include <typeinfo>
#include <iostream>

static void
g()
{
{
class A {} ;
std::cout << typeid( A ).name() << std::endl ;
}
{
class A {} ;
std::cout << typeid( A ).name() << std::endl ;
}
}

class A
{
} ;

namespace NS { class A {} ; }

int
main()
{
extern void f() ;
std::cout << typeid( A ).name() << std::endl ;
std::cout << typeid( NS::A ).name() << std::endl ;
g() ;
f() ;
return 0 ;
}

typeid2.cc

#include <typeinfo>
#include <iostream>

static void
g()
{
{
class A {} ;
std::cout << typeid( A ).name() << std::endl ;
}
{
class A {} ;
std::cout << typeid( A ).name() << std::endl ;
}
}

void
f()
{
g() ;
}

(Note that the definitions of class A in g() are at exactly the
same line in both files---VC++ encodes the line number of a
local class in its name, so they only have the same name if they
are defined on the same line.)
 

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

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top