   Strings from C++ template arguments.
  Hello. I want to get an ASCII string for the name of the class to which a template argument is instantiated.The functionality should basically be enough to do this:Quote:template<typename T>void test(T arg){cout << arg << " is of type " << STRING_THINGY(T) << "!\n";}test(123);// prints "123 is of type int!\n";test("abc")// prints "abc is of type char*!\n";RTTI is no good since it's only for polymorphic types. Macros are no good since they're applied before templates are.   
  Use typeidIt's a C++ keywordthe following will get what you wanttemplate<class T>class Test{public:  Test(){    std::cout << typeid(T).name() << std::endl;  }};;Quote:Original post by G-ForceUse typeidNote that typeid does not depend on polymorphic types.  It will only give you the base class if you typeid a pointer of that type and it isn't polymorphic, but that's not an issure here.Also note that while on some platforms name() is legible, on others it is not. GCC spits out stuff like "v" for void, "u" for unsigned int, etc. for other primitives, and other manglings for classes.  If legible types is a must, you must do the legwork yourself.  Here's how I'd do it off the top of my head (disclaimer: untested, may not compile):EDIT: Evil source tags like to eat my "\"s.  Extra spaces added, delete them if copy/pasted :P.  Also note you'll have to manually specialize types with commas in their name (e.g. std::vector< int , std::allocator< int > >) since it'll try to match that as a macro argument seperator (and extra parens don't work so well here)template < typename T > struct type_information;#define REGISTER_TYPE( type )   \ template <> struct type_information< type > {  \static const char * name() throw() {  \    return #type; \}  \ };REGISTER_TYPE( int )REGISTER_TYPE( char )...template < typename T > void test( T arg ) {    cout << arg << " is of type " << type_information< T >::name() << end;};Quote:Original post by MaulingMonkeyNote that typeid does not depend on polymorphic types.  It will only give you the base class if you typeid a pointer of that type and it isn't polymorphic, but that's not an issure here.Then there's no reason to raise the issue and confuse matters.Quote:Also note that while on some platforms name() is legible, on others it is not. GCC spits out stuff like "v" for void, "u" for unsigned int, etc. for other primitives, and other manglings for classes.  If legible types is a must, you must do the legwork yourself.Use abi::__cxa_demangle().   ;Quote:Original post by FrunyQuote:Original post by MaulingMonkeyNote that typeid does not depend on polymorphic types.  It will only give you the base class if you typeid a pointer of that type and it isn't polymorphic, but that's not an issure here.Then there's no reason to raise the issue and confuse matters.I was trying to clarify - I suspected the OP meant this when he refered to RTTI (since he wrote off RTTI as a possibility, and could not think of a way it applied except via the typeid operator), and wished to indicate that, no, typeid() works fine independantly of RTTI.Quote:Quote:Also note that while on some platforms name() is legible, on others it is not. GCC spits out stuff like "v" for void, "u" for unsigned int, etc. for other primitives, and other manglings for classes.  If legible types is a must, you must do the legwork yourself.Use abi::__cxa_demangle().Yes, probably better here :).   ;Quote:Original post by MaulingMonkeyI was trying to clarify - I suspected the OP meant this when he refered to RTTI (since he wrote off RTTI as a possibility, and could not think of a way it applied except via the typeid operator), and wished to indicate that, no, typeid() works fine independantly of RTTI.Fair enough.   ;Quote:Original post by MaulingMonkeyI was trying to clarify - I suspected the OP meant this when he refered to RTTI (since he wrote off RTTI as a possibility, and could not think of a way it applied except via the typeid operator), and wished to indicate that, no, typeid() works fine independantly of RTTI.Maybe it's some microsoft specific behaviour, but on MSDN doc for typeid is is said that:Quote:If the pointer does not point to a valid object, a __non_rtti_object exception is thrown, indicating an attempt to analyze the RTTI that triggered a fault (like access violation), because the object is somehow invalid (bad pointer or the code wasn't compiled with /GR).(where /GR means that runtime type info is enabled) The /GR documentation also states clearly that RTTI has to be enabled for whoever wants to use either dynamic_cast or typeid.So this leaves me a bit confused...  What do you think ?   ;  If one needs to demangle names in visual studio, use UnDecorateSymbolName in DbgHelp.dll.  Just wanted to let you know in case your adventures require it.   ;Quote:Original post by jantaMaybe it's some microsoft specific behaviour, but on MSDN doc for typeid is is said that:Quote:If the pointer does not point to a valid object, a __non_rtti_object exception is thrown, indicating an attempt to analyze the RTTI that triggered a fault (like access violation), because the object is somehow invalid (bad pointer or the code wasn't compiled with /GR).(where /GR means that runtime type info is enabled) The /GR documentation also states clearly that RTTI has to be enabled for whoever wants to use either dynamic_cast or typeid.So this leaves me a bit confused...  What do you think ?With regards to typeid(), this only applies to checking dereferenced pointers/references to polymorphic types.  With /GR- on VS2k5E, this compiles and runs fine without warning:#include <iostream>using namespace std;struct foo {};struct bar : foo {};int main () {    bar b;    foo * f = &b;    cout << "typeid( *f ).name() == " << typeid( *f ).name() << endl;}The result is foo, even though *f is of type bar - this is standard behavior, for foo is not polymorphic.Adding a virtual table to foo:#include <iostream>using namespace std;struct foo { virtual ~foo() {} };struct bar : foo {};int main () {    bar b;    foo * f = &b;    cout << "typeid( *f ).name() == " << typeid( *f ).name() << endl;}We get a warning compiling:1>.\main.cpp(10) : warning C4541: 'typeid' used on polymorphic type 'foo' with /GR-; unpredictable behavior may resultAnd the program crashes at runtime.  Switching both instances of "*f" (the pointer-to-polymorphic-type-unknown-until-runtime) with "foo" (the static type) or "b" (of a polymorphic type but determinable at compile time) and the program will compiles and runs fine with no warnings as expected (displaying foo and bar respectively).All this said and done, since the OP is passing the type in question by value, unless he's making pointers for no good reason, typeid() will work fine, especially if he uses typeid(T), since the compiler can determine at compile time the type, and thus no dependance on Run Time Type Information.   