この 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 件のコメント:
コメントを投稿