I would like to use the name of a type at compile time. For example, suppose I\'ve written:
constexpr size_t my_strlen(const char* s)
{
const char* c
(Based on @melak47's gist and using C++17):
#using
// and if it's not C++17, take the GSL implementation or just roll your own struct -
// you only need to implement 3 or 4 methods here.
namespace detail {
template
constexpr const char* templated_function_name_getter() {
#if defined(__GNUC__) || defined(__clang__)
return __PRETTY_FUNCTION__;
#elif defined(_MSC_VER)
return __FUNCSIG__;
#else
#error unsupported compiler (only GCC, clang and MSVC are supported)
#endif
}
} // namespace detail
template
constexpr std::string_view type_name() {
constexpr std::string_view funcsig = detail::templated_function_name_getter();
// Note: The "magic numbers" below
#if defined(__GNUC__) || defined(__clang__)
constexpr auto start_bit = std::string_view{"T = "};
constexpr auto end_bit = std::string_view{"]"};
#elif defined(_MSC_VER)
constexpr auto start_bit = std::string_view{"detail::templated_function_name_getter<"};
constexpr auto end_bit = std::string_view{">("};
#else
#error unsupported compiler (only GCC, clang and MSVC are supported)
#endif
constexpr auto start = funcsig.find(start_bit);
constexpr auto end = funcsig.rfind(end_bit);
static_assert(
start != funcsig.npos and end != funcsig.npos and end > start,
"Failed parsing the __PRETTY_FUNCTION__/__FUNCSIG__ string");
}
return funcsig.substr(start + start_bit.size(), end - start - start_bit.size());
}
Note: There's now a nicer version of this approach implemented here.