簡體   English   中英

來自 int 的強類型枚舉。 C++11

[英]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應該做的。

我想避免ifswitch 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++ 枚舉的三個問題:

  • 常規枚舉隱式轉換為 int
  • 常規枚舉將其值導出到周圍的 scope
  • 無法指定常規枚舉的基礎類型

如果您將enum用於 IO,您將不得不在某個時候轉換它們。 您的enum被定義為一個連續的范圍 您可以添加FirstLast值並檢查范圍( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM