Print template typename at compile time
To get a useful compile time name:
Supposing you have some unknown type named 'T'. You can get the compiler to print it's type by using it horribly. For example:
typedef typename T::something_made_up X;
The error message will be like:
error: no type named 'something_made_up' in 'Wt::Dbo::ptr<trader::model::Candle>'
The bit after 'in' shows the type. (Only tested with clang).
Other ways of triggering it:
bool x = T::nothing; // error: no member named 'nothing' in 'Wt::Dbo::ptr<trader::model::Candle>'
using X = typename T::nothing; // error: no type named 'nothing' in 'Wt::Dbo::ptr<trader::model::Candle>'
With C++11, you may already have an object and use 'decltype' to get its type, so you can also run:
auto obj = creatSomeObject();
bool x = decltype(obj)::nothing; // (Where nothing is not a real member).
__PRETTY_FUNCTION__
should solve your problem (at run time at least)
The output to the program below is:
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf test<type>::test() [with type = int]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
asfdasdfasdf void tempFunction() [with type = bool]
!!!Hello World!!!
If you really, really, need the typename as a string, you could hack this (using snprintf
instead of printf
) and pull the substring after '=' and before ']'.
#include <iostream>
using namespace std;
template<typename type>
class test
{
public:
test()
{
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
}
};
template<typename type>
void tempFunction()
{
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
printf("asfdasdfasdf %s\n", __PRETTY_FUNCTION__);
}
int main() {
test<int> test;
tempFunction<bool>();
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
Since you have said you would need this for debugging purpose, maybe a runtime solution is also acceptable. And you have tagged this as g++ so you don't want to be standard conform.
Here is what that means:
#include <cxxabi.h> // the libstdc++ used by g++ does contain this header
template <typename type>
void print(const type *addr) // you wanted a pointer
{
char * name = abi::__cxa_demangle(typeid(*addr).name(), 0, 0, NULL);
printf("type is: %s\n", name);
free(name);
}
print(new unsigned long); // prints "type is: unsigned long"
print(new std::vector<int>); // prints "type is: std::vector<int, std::allocator<int> >"
EDIT: corrected the memory leak. Thx to Jesse.