[英]Why can't C++11 strongly-typed enum be cast to underlying type via pointer?
[英]strongly typed enum from int . C++11
我們最近將所有枚舉轉換為 class 枚舉。
enum class Launches : std::uint32_t {
D_FROM_FILE=0,
D_FROM_FDISK,
D_FROM_RDDISK,
D_FROM_USB,
D_FROM_UI,
D_FROM_NET,
D_FROM_DEFAULT
};
Launches launches ;
我需要根據從命令行收到的 int 分配launches
值
這就是我在轉換為強類型枚舉后所做的事情
if (receivedInt == 1)
launches = D_FROM_FDISK;
我想避免並喜歡
launches = receivedInt;
我們無法編譯,因為這是強類型int
應該做的。
我想避免if
和switch
case on receivedInt
。
launches = (Launches)receivedInt ; // this compiles ..
但我對此或使用static_cast
猶豫不決......正確的方法是什么?
使用static_cast
等? 那么使用強類型枚舉會有什么好處呢?
如果您不想進行類型轉換,您可以使用 unordered_map。 這是一個示例,它將您可以從命令行獲取的 int 以類型安全的方式轉換為枚舉值
#include <cassert>
#include <string>
#include <unordered_map>
enum class Launches
{
D_FROM_FILE = 0,
D_FROM_FDISK,
D_FROM_RDDISK,
D_FROM_USB,
D_FROM_UI,
D_FROM_NET,
D_FROM_DEFAULT
};
Launches get_option(const int option)
{
static const std::unordered_map<int, Launches> launch_options
{
{1, Launches::D_FROM_FILE},
{2, Launches::D_FROM_FDISK},
//.. etc..
{6, Launches::D_FROM_NET}
};
auto it = launch_options.find(option);
if (it != launch_options.end())
{
return it->second;
}
return Launches::D_FROM_DEFAULT;
}
int main()
{
auto option = get_option(1);
assert(option == Launches::D_FROM_FILE);
return 0;
}
你可以做什么, - 創建一個簡單的轉換 function,檢查 rages 然后進行簡單的類型轉換。
#include <system_error>
...
Launches from_code(std::error_code& ec,int code) noexcept
{
Launches ret = Launches::D_FROM_DEFAULT;
if( code < 0 || code > 7) {
ec = std::make_error_code(std::errc::invalid_argument);
} else {
ret = static_cast<Launches>( static_cast<uint32_t>(code) );
}
return ret;
}
std::error_code ec;
Lanches launches = from_code(ec,code);
if(ec) {
// handle error, this code simply thows you can insert your safe logic
throw std::system_error(ec);
}
// do what ever you need to
switch(launches) {
case Launches::D_FROM_FILE:
...
break;
...
}
Stroustrup - enum
類解決了傳統 c++ 枚舉的三個問題:
如果您將enum
用於 IO,您將不得不在某個時候轉換它們。 您的enum
被定義為一個連續的范圍。 您可以添加First
和Last
值並檢查范圍( demo ):
#include <iostream>
#include <exception>
enum class Launches : std::uint32_t
{
First = 0,
D_FROM_FILE = First,
D_FROM_FDISK,
D_FROM_RDDISK,
D_FROM_USB,
D_FROM_UI,
D_FROM_NET,
D_FROM_DEFAULT,
Last = D_FROM_DEFAULT
};
template< typename E, typename T >
Launches seq_enum_cast(T v)
{
return v >= static_cast<T>(E::First) && v <= static_cast<T>(E::Last)
? static_cast<E>(v)
: throw std::bad_cast();
}
int main()
{
try
{
auto a = seq_enum_cast<Launches>(1);
std::cout << "a - success\n";
auto b = seq_enum_cast<Launches>(-3); // fails
std::cout << "b - success\n";
}
catch (const std::bad_cast& e)
{
std::cout << e.what();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.