Skip to content

Instantly share code, notes, and snippets.

@remyroez
Last active November 2, 2016 07:09
Show Gist options
  • Save remyroez/811a0cd0fbffa2eacbe84e72bec000f4 to your computer and use it in GitHub Desktop.
Save remyroez/811a0cd0fbffa2eacbe84e72bec000f4 to your computer and use it in GitHub Desktop.
SFINAE 安全な underlying_type
#include <iostream>
#include <type_traits>
template <typename T, typename = typename std::is_enum<T>::type>
struct safe_underlying_type { using type = T; };
template <typename T>
struct safe_underlying_type<T, std::true_type> { using type = std::underlying_type_t<T>; };
template <typename T>
using safe_underlying_type_t = typename safe_underlying_type<T>::type;
template <typename T>
constexpr safe_underlying_type_t<T> underlying_cast(T t) noexcept { return static_cast<safe_underlying_type_t<T>>(t); }
enum class foo : int { hoge, fuga };
enum class bar : char { hoge, fuga };
struct baz { int value; };
int main()
{
static_assert(!std::is_same<safe_underlying_type_t<foo>, int>::value, "foo is enum:int");
static_assert(!std::is_same<safe_underlying_type_t<bar>, char>::value, "bar is enum:char");
static_assert(std::is_same<safe_underlying_type_t<baz>, int>::value, "baz isn't enum");
baz a{123};
baz b = underlying_cast(a);
std::cout << a.value << std::endl;
std::cout << b.value << std::endl;
return 0;
}
@remyroez
Copy link
Author

remyroez commented Nov 2, 2016

Add underlying_cast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment