For example:
int a = 12;
cout << typeof(a) << endl;
Expected output:
int
Howard Hinnant used magic numbers to extract type name. 康桓瑋 suggested string prefix and suffix. But prefix/suffix keep changing. With “probe_type” type_name automatically calculates prefix and suffix sizes for “probe_type” to extract type name:
#include
using namespace std;
namespace typeName {
template
constexpr string_view wrapped_type_name () {
#ifdef __clang__
return __PRETTY_FUNCTION__;
#elif defined(__GNUC__)
return __PRETTY_FUNCTION__;
#elif defined(_MSC_VER)
return __FUNCSIG__;
#endif
}
class probe_type;
constexpr string_view probe_type_name ("typeName::probe_type");
constexpr string_view probe_type_name_elaborated ("class typeName::probe_type");
constexpr string_view probe_type_name_used (wrapped_type_name ().find (probe_type_name_elaborated) != -1 ? probe_type_name_elaborated : probe_type_name);
constexpr size_t prefix_size () {
return wrapped_type_name ().find (probe_type_name_used);
}
constexpr size_t suffix_size () {
return wrapped_type_name ().length () - prefix_size () - probe_type_name_used.length ();
}
template
string_view type_name () {
constexpr auto type_name = wrapped_type_name ();
return type_name.substr (prefix_size (), type_name.length () - prefix_size () - suffix_size ());
}
}
#include
using typeName::type_name;
using typeName::probe_type;
class test;
int main () {
cout << type_name () << endl;
cout << type_name () << endl;
cout << type_name () << endl;
const int ic = 42;
const int* pic = ⁣
const int*& rpic = pic;
cout << type_name () << endl;
cout << type_name () << endl;
cout << type_name () << endl;
cout << type_name () << endl;
}
Output
gcc 10.2:
test
const int *&
unsigned int
const int
const int *
const int *&
typeName::probe_type
clang 11.0.0:
test
const int *&
unsigned int
const int
const int *
const int *&
typeName::probe_type
VS 2019 version 16.7.6:
class test
const int*&
unsigned int
const int
const int*
const int*&
class typeName::probe_type