[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

unscrambling typeid().name

Deepak Jharodia

9/30/2008 7:02:00 AM

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
7 Answers

Gianni Mariani

9/30/2008 9:57:00 AM

0

Deepak Jharodia wrote:
> 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.

James Kanze

9/30/2008 10:09:00 AM

0

On Sep 30, 11:57 am, Gianni Mariani <gi4nos...@mariani.ws> wrote:
> Deepak Jharodia wrote:
> > 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.

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:james.kanze@gmail.com
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

Salt_Peter

9/30/2008 10:11:00 AM

0

On Sep 30, 3:01 am, Deepak Jharodia <deepakjharo...@gmail.com> wrote:
> 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.

Deepak Jharodia

9/30/2008 11:36:00 AM

0

On Sep 30, 3:10 pm, Salt_Peter <pj_h...@yahoo.com> wrote:
> On Sep 30, 3:01 am, Deepak Jharodia <deepakjharo...@gmail.com> wrote:
>
> > 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.

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.

Deepak Jharodia

9/30/2008 11:38:00 AM

0

On Sep 30, 3:08 pm, James Kanze <james.ka...@gmail.com> wrote:
> On Sep 30, 11:57 am, Gianni Mariani <gi4nos...@mariani.ws> wrote:
>
> > Deepak Jharodia wrote:
> > > 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.
>
> 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:james.ka...@gmail.com
> 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.

Marco Manfredini

9/30/2008 1:22:00 PM

0

Deepak Jharodia wrote:

> 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/bk01pt1...

James Kanze

10/1/2008 7:50:00 AM

0

On Sep 30, 1:37 pm, Deepak Jharodia <deepakjharo...@gmail.com> wrote:
> On Sep 30, 3:08 pm, James Kanze <james.ka...@gmail.com> wrote:
> > On Sep 30, 11:57 am, Gianni Mariani <gi4nos...@mariani.ws> wrote:

> > > Deepak Jharodia wrote:
> > > > 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.

> > 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.)

> 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.)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
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