Skip to content

Instantly share code, notes, and snippets.

@remyroez
Created November 10, 2016 09:19
Show Gist options
  • Save remyroez/19934d8df6a1ae5040ab5f1859658342 to your computer and use it in GitHub Desktop.
Save remyroez/19934d8df6a1ae5040ab5f1859658342 to your computer and use it in GitHub Desktop.
タイプ名のデマングル
#include <iostream>
#include <sstream>
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
std::string demangle(const char *name) {
int status = 0;
std::unique_ptr<char, decltype(&std::free)> resource {
abi::__cxa_demangle(name, nullptr, nullptr, &status),
std::free
};
return (status == 0) ? resource.get() : name;
}
#else
std::string demangle(const char *name) { return name; }
#endif
template <typename T>
std::string type_name() {
std::stringstream ss;
if (std::is_const<T>::value) ss << "const ";
if (std::is_volatile<T>::value) ss << "volatile ";
ss << demangle(typeid(*(std::remove_reference_t<std::remove_cv_t<T>>*)nullptr).name());
if (std::is_lvalue_reference<T>::value) ss << " &";
if (std::is_rvalue_reference<T>::value) ss << " &&";
return ss.str();
}
template <typename T>
std::string type_name(const T &) { return type_name<T>(); }
// ----------
struct foo {};
template <typename T, typename U>
auto bar(const T &t, const U &u) { return t + u; }
auto baz() {
struct s {};
return s{};
}
int main()
{
auto a = bar(100.0f, 200U);
std::cout << type_name(a) << " a = " << a << std::endl;
auto b = (int *)nullptr;
std::cout << type_name(b) << " b = " << b << std::endl;
std::cout << type_name(123LL) << std::endl;
std::cout << type_name<const volatile int>() << std::endl;
std::cout << type_name<double &>() << std::endl;
std::cout << type_name<foo &&>() << std::endl;
std::cout << type_name(baz()) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment