There is no requirement on what type_info::name()
looks like.
The result of a
typeid
expression is an lvalue of static typeconst std::type_info
(18.7.1) and dynamic typeconst std::type_info
orconst name
where name is an implementation-defined class publicly derived fromstd::type_info
Then, about std::type_info::name()
:
const char* name() const;
Returns: an implementation-defined NTBS.
[...]
NTBS is simply a shorthand for null-terminated byte string.
In other words: You should not rely on any value of type_info::name()
.
What you actually see with g++:
Those names are mangled names, and g++'s implementation of such mangled names is based on length-prefixed strings, where each substring is the namespace name, plus some other info; but that's basically it.
For example:
unmangled: foo::bar::Frob
mangled: 3foo3bar4Frob
Example to put into your compiler:
#include <iostream>
#include <typeinfo>
namespace foo { namespace bar {
enum Frob {};
class Frobnicate {};
Frob frob;
template <typename T> void Meh() { throw T(); }
} }
int main () {
std::cout << typeid(foo::bar::Frob).name() << '\n'
<< typeid(foo::bar::Frobnicate).name() << '\n'
<< typeid(foo::bar::frob).name() << '\n'
<< typeid(foo::bar::Meh<int>).name() << '\n'
<< typeid(foo::bar::Meh<float>).name() << '\n'
;
}
Output for me:
N3foo3bar4FrobE
N3foo3bar10FrobnicateE
N3foo3bar4FrobE
FvvE
FvvE
The latter two show you that one even cannot rely on names being different.