[英]strongly typed enum from int . C++11
We are recently converting all enum to class enum.我们最近将所有枚举转换为 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 ;
I need to assign launches
values based on int that i received from command line我需要根据从命令行收到的 int 分配
launches
值
This is what I am doing after conversion to strongly typed enum这就是我在转换为强类型枚举后所做的事情
if (receivedInt == 1)
launches = D_FROM_FDISK;
I want to avoid and do like我想避免并喜欢
launches = receivedInt;
We fail to compile as this is what strongly typed int
are supposed to do.我们无法编译,因为这是强类型
int
应该做的。
I want to avoid if
and switch
cases on receivedInt
.我想避免
if
和switch
case on receivedInt
。
launches = (Launches)receivedInt ; // this compiles ..
but I am hesitant on this or on using static_cast
... whats the proper way?但我对此或使用
static_cast
犹豫不决......正确的方法是什么?
using static_cast
etc?使用
static_cast
等? What benefit will remain on using strongly types enums then那么使用强类型枚举会有什么好处呢?
If you don't want to do typecasts you can use an unordered_map.如果您不想进行类型转换,您可以使用 unordered_map。 Here is an example that converts an int you could get from commandline into an enum value in a typesafe manner
这是一个示例,它将您可以从命令行获取的 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;
}
What you can do, - create a simple conversion function, check rages and then do the trivial type casting.你可以做什么, - 创建一个简单的转换 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 - The enum
classes address three problems with conventional c++ enumerations: Stroustrup -
enum
类解决了传统 c++ 枚举的三个问题:
If you use enum
s for IO, you will have to convert them at some point.如果您将
enum
用于 IO,您将不得不在某个时候转换它们。 Your enum
is defined as a continuous range .您的
enum
被定义为一个连续的范围。 You could add a First
and a Last
value and check the range ( demo ):您可以添加
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.