Is it possible in standard C++ to print a variable type. I think this is being addressed in C++0x but not sure it already exists.
I would like something like this:
int a = 12;
cout << typeof(a) << endl;
That would print:
int
Is it possible in standard C++ to print a variable type. I think this is being addressed in C++0x but not sure it already exists.
I would like something like this:
int a = 12;
cout << typeof(a) << endl;
That would print:
int
Try
cout << typeid(a).name() << endl;
You might have to activate RTTI in your compiler options for this to work. Additionally, the output of this depends on the compiler. It might be a raw type name or a name mangling symbol or anything in between.
You may be looking for this: http://www.boostpro.com/vault/
look for the file identification-v0.1.zip
EDIT: Beaten, serves me right for looking it up =]. Don't forget to include <typeinfo>
I believe what you are referring to is runtime type identification. You can achieve the above by doing .
#include <iostream>
#include <typeinfo>
using namespace std;
int main() {
int i;
cout << typeid(i).name();
return 0;
}
You could use a traits class for this. Something like:
#include <iostream>
using namespace std;
template <typename T> class type_name {
public:
static const char *name;
};
#define DECLARE_TYPE_NAME(x) template<> const char *type_name<x>::name = #x;
#define GET_TYPE_NAME(x) (type_name<typeof(x)>::name)
DECLARE_TYPE_NAME(int);
int main()
{
int a = 12;
cout << GET_TYPE_NAME(a) << endl;
}
The DECLARE_TYPE_NAME
define exists to make your life easier in declaring this traits class for all the types you expect to need.
This might be more useful than the solutions involving typeid
because you get to control the output. For example, using typeid
for long long
on my compiler gives "x".
You can use templates.
template <typename T> const char* typeof(T&) { return "unknown"; } // default
template<> const char* typeof(int&) { return "int"; }
template<> const char* typeof(float&) { return "float"; }
In the example above, when the type is not matched it will print "unknown".
Note that the names generated by the RTTI feature of C++ is not portable. For example, the class
MyNamespace::CMyContainer<int, test_MyNamespace::CMyObject>
will have the following names:
// MSVC 2003:
class MyNamespace::CMyContainer[int,class test_MyNamespace::CMyObject]
// G++ 4.2:
N8MyNamespace8CMyContainerIiN13test_MyNamespace9CMyObjectEEE
So you can't use this information for serialization. But still, the typeid(a).name() property can still be used for log/debug purposes
The other answers involving RTTI (typeid) are probably what you want, as long as:
The alternative, (similar to Greg Hewgill's answer), is to build a compile-time table of traits.
template <typename T> struct type_as_string;
// declare your Wibble type (probably with definition of Wibble)
template <> struct type_as_string<Wibble> { static const char* const value = "Wibble"; };
Be aware that if you wrap the declarations in a macro, you'll have trouble declaring names for template types taking more than one parameter (e.g. std::map), due to the comma.
To access the name of the type of a variable, all you need is
template <typename T>
const char* get_type_as_string(const T&) { return type_as_string<T>::value; }