Если это для целей отладки, то это решение будет работать без каких-либо зависимостей:
#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;
}
В отличие от ответа на основе typeid
, здесь используется препроцессор, и поэтому он не подлежит искажению имени (поэтому имя ... читабельно ).
Обратите внимание, что вы не можете использовать v.value_type
как тип напрямую, это не часть экземпляра v
, а типа v
: std::vector<std::string>
Часть регулярного выражения заключается в том, что класс std::string
слишком тупой, и вам нужны такие странности для простого кода поиска / разбиения. Если у вас есть достойный класс строки, вам не понадобится регулярное выражение для извлечения части, которая находится после строки "=" и перед ";".