When creating a template function in C++ is there a simple way to have the typename of the template represented as a string? I have a simple test case to show what I\'m try
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);
delete 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.
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).
Another compile time solution, similar to the one provided by matiu, but perhaps a little more descriptive would be to use a static_assert
wrapped in a little helper function:
template <typename T>
void print_type_in_compilation_error(T&&)
{
static_assert(!std::is_same<T, int>::value &&
std::is_same<T, int>::value,
"Compilation failed because you wanted to know the type; see below:");
}
// usage:
int I;
print_type_in_compilation_error(I);
The above will give you a nice error message (tested in MSVC and Clang), as in the other answer, but the code is easier to understand in my opinion.
__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;
}
if you have a known set of types used instantiate the template we can use the approach described in this older thread: stackoverflow.com/questions/1055452
There is Boost.TypeIndex library.
See boost::typeindex::type_id for details.
It is very-easy-to-use, cross-platform and is real compile-type solution. Also it works as well even if no RTTI available. Also most of compilers are supported from the box.