If it's for debug purpose, then this solution would work without any dependencies:
#include <regex>
template <typename T>
struct TypeToNameT
{
static std::string getTypeFromName() {
#ifdef _MSC_VER
std::regex re("<(.*)>::.*");
std::string templateType(__FUNCTION__);
#else
std::regex re(" = (.*);");
std::string templateType(__PRETTY_FUNCTION__);
#endif
std::smatch match;
try
{
if (std::regex_search(templateType, match, re) && match.size() > 1)
return match.str(1);
}
catch (std::regex_error& e) {
// Syntax error in the regular expression
}
return "";
}
};
/** Get the templated type name. This does not depends on RTTI, but on the preprocessor, so it should be quite safe to use even on old compilers */
template <typename T>
std::string getTypeName() { return TypeToNameT<T>::getTypeFromName(); }
int main() {
std::vector<std::string> v = {"apple", "facebook", "microsoft", "google" };
std::cout << getTypeName<decltype(v)::value_type>() << std::endl; // Returns: "std::__cxx11::basic_string<char>"
return 0;
}
Unlike the typeid
based answer, this use the preprocessor and as such is not subject to name mangling (so the name is... readable).
Please notice that you can't use v.value_type
as a type directly, it's not part of the instance v
but of the type of v
: std::vector<std::string>
The regex part is because the std::string
class is too dumb and you need such oddities for a simple search/split code. If you have a decent string class, you'll not need regex here for extracting the part that's after the "=" string and before the ";".