Is it possible in C++ to stringify template arguments? I tried this:
#define STRINGIFY(x) #x
template <typename T>
struct Stringify
{
Stringify()
{
cout<<STRINGIFY(T)<<endl;
}
};
int main()
{
Stringify<int> s;
}
But what I get is a 'T', and not an 'int'. Seems that the preprocessors kicks in before template resolution.
Is there any other way to do this?
Is there any way for the preprocessing to take place after template resolution? (Compiler is VC++).
You could try
Edit: Fixed based on comments.
You could use some template magic.
This has an advantage over RTTI (i.e.
typeinfo
) - it is resolved during compilation; and disadvantage - you need to provide type information yourself (unless there is some library that does that already that I'm not aware of; maybe something in Boost even).Or, as Matrin York suggested in comments, use inline function templates instead:
But, if you'll ever need to store more information about that particular type, then class templates will probably be better.
Here’s what I do: I have a
demangle()
function (implemented on top ofabi::__cxa_demangle()
which I call with a couple of convenience template function overloads,nameof()
, with either the type I want stringified or an instance of same.It’s fairly compact, so I’ll reproduce it here in all its glory. In
demangle.hh
we have:… And then in
demangle.cpp
:To use this, I think you’ll have to link to
libc++
(or whatever your local equivalent is) to useabi::__cxa_demangle()
. What may be suboptimal for the OP is the fact that this does the demangling and stringification at runtime. I’d personally love somethingconstexpr
-friendly in leu of this, but since I suffer from a severe macro-abuse allergy, I find this to be the least generally-unreasonable solution to this problem.(the
terminator
namespace is inconsequential – I use this code in a libunwind-based stacktracer called from termination handler – feel free tos///g
that token)This breaks one of my primary tenets of C++ code writing: Avoid using tricks in both the template features and the preprocessor at the same time.
Part of the reason for templates and the nastiness they introduce into the language was an attempt to wean developers away from using the preprocessor. If you use both, then the terrorists win.
No, you cannot work on types as if they were variables. You could write code that extracted the typeid() of an element and printed the name, but the resulting value will probably not be what you expect (type names are not standarized).
You can also work with template specializations (and some macro magic) to achieve a more interesting version if the number of types you want to work with is limited:
Or you could even combine both versions: implement the printtype generic template using typeinfo and then provide specializations for the types you want to have fancier names.
in my code I use the "awful" double-declaration of the "Class-Name"
because c++ is NOT able to extract the string "MyServer" from the template… the only "way" to get "rid" of this… using a cpp "wrapper"