This needs only work in g++.
I want a function
template<typename T> std::string magic();
such that:
Class Foo{}; magic<Foo>(); // returns "Foo";
Class Bar{}; magic<Bar>(); // returns "B开发者_如何转开发ar";
I don't want this to be done via specialization (i.e. having to define magic for each type. I'm hoping to pull some macro/template black magic here. Anyone know how?)
Thanks!
To convert a type (or other identifer) into a string you need a macro, but a macro can not check if it's parameter is a valid type. To add type checking a template function can be added to the macro:
template<typename T>
std::string magic_impl(const char *name) { return name; }
#define more_magic(a) magic_impl<a>(#a)
#define magic(a) more_magic(a)
Here magic(int)
gives the string "int"
while magic(Foo)
gives a "‘Foo’ was not declared" error if there is no such class.
Try typeid(Foo).name()
for a start. Parse as you see fit; will be implementation-dependent (but simply getting a string back is portable).
The stringizing operator on macros may be what you're looking for:
#define MAGICCLASSNAME(str) std::string magic(#str)
class Foo{}; MAGICCLASSNAME(foo)
I have come up with the below:
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
class Foo{};
class Bar{};
template<typename T>
inline std::string magic(const T& obj)
{
return typeid(obj).name();
}
int main()
{
Foo a;
cout << magic<Foo>(a); // returns "Foo";
}
I tested this with g++ and works well.
Also I got it from this SO answer.
精彩评论