Last active
November 2, 2016 07:09
-
-
Save remyroez/811a0cd0fbffa2eacbe84e72bec000f4 to your computer and use it in GitHub Desktop.
SFINAE 安全な underlying_type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add underlying_cast.