この std::underlying_type を使うことで、enum を安全に整数型にキャストすることができます。
以下の例では、int型では表せない enum class型が定義されています。これを整数型に変換するには注意を要します。
#include <cstdint> #include <iostream> // Enum::LARGEはint型では表せない enum class Enum : std::uint64_t { LARGE = 0xFFFFFFFFFFFFFFFF }; int main(void) { // enum classは型に対して厳密なので、暗黙の内の変換はできない std::cout << Enum::LARGE << std::endl; // コンパイルエラー! // intへの誤変換 std::cout << static_cast<int>(Enum::LARGE); // => "-1" // 正しい変換 // しかし、enumのベース型を意識する必要がある std::cout << static_cast<std::uint64_t>(Enum::LARGE); // => "18446744073709551615" return 0; }std::underlying_type で enum のベース型を取得できるので、簡単な関数を一つ定義することで、どのような enum であっても、安全に整数型に変換することができます。
関数の実装例は以下のようになります。
#include <cstdint> #include <iostream> #include <type_traits> // enum型をベースの整数型へ変換する関数 e2i() template <typename ENUM> typename std::underlying_type<ENUM>::type e2i(ENUM e) { static_assert(std::is_enum<ENUM>::value, "e2i() requires enum argument"); // for safety return static_cast<typename std::underlying_type<ENUM>::type>(e); } // Enum::LARGEはint型では表せない enum class Enum : std::uint64_t { LARGE = 0xFFFFFFFFFFFFFFFF }; int main(void) { // ベース型を意識せずに整数型へ変換可能 std::cout << e2i(Enum::LARGE) << // => "18446744073709551615" return 0; }
0 件のコメント:
コメントを投稿