我們最近將所有 enum 轉換為類 enum 。
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 ;
我需要launches根據從命令列收到的 int分配值
這就是我在轉換為強型別列舉后所做的事情
if (receivedInt == 1)
launches = D_FROM_FDISK;
我想避免并喜歡
launches = receivedInt;
我們無法編譯,因為這是強型別int應該做的。
我想避免if和switch案例receivedInt。
launches = (Launches)receivedInt ; // this compiles ..
但我對此或使用猶豫不決static_cast......正確的方法是什么?
使用static_cast等?那么使用強型別列舉會有什么好處呢?
uj5u.com熱心網友回復:
如果您不想進行型別轉換,您可以使用 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;
}
uj5u.com熱心網友回復:
你可以做什么, - 創建一個簡單的轉換函式,檢查憤怒,然后進行瑣碎的型別轉換。
#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;
...
}
uj5u.com熱心網友回復:
Stroustrup - 這些enum類解決了傳統 c 列舉的三個問題:
- 常規列舉隱式轉換為 int;
- 常規列舉將其值匯出到周圍范圍;
- 無法指定常規列舉的基礎型別。
如果將enums 用于 IO,則必須在某些時候轉換它們。你enum被定義為一個連續的范圍。您可以添加一個First和一個Last值并檢查范圍(演示):
#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();
}
}
如果您可以定義未使用的列舉器,則可以使用以下定義(并相應地更改驗證),這似乎不太容易出錯:
enum class Launches : std::uint32_t
{
First = 0,
D_FROM_FILE = First,
//...
D_FROM_DEFAULT,
Last
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/406659.html
標籤:
上一篇:將二維陣列作為函式引數傳遞
