最新の C++ で列挙型を文字列に変換する方法 質問する

最新の C++ で列挙型を文字列に変換する方法 質問する

他の同様の質問とは異なり、この質問は新しい C++ 機能の使用に関するものです。

多くの回答を読んだ後も、まだ何も見つかりませんでした:

長い説明よりも例の方がわかりやすいです。
このスニペットをコンパイルして実行することができます。コリル.
もう一つの例もご利用いただけます)

#include <map>
#include <iostream>

struct MyClass
{
    enum class MyEnum : char {
        AAA = -8,
        BBB = '8',
        CCC = AAA + BBB
    };
};

// Replace magic() by some faster compile-time generated code
// (you're allowed to replace the return type with std::string
// if that's easier for you)
const char* magic (MyClass::MyEnum e)
{
    const std::map<MyClass::MyEnum,const char*> MyEnumStrings {
        { MyClass::MyEnum::AAA, "MyClass::MyEnum::AAA" },
        { MyClass::MyEnum::BBB, "MyClass::MyEnum::BBB" },
        { MyClass::MyEnum::CCC, "MyClass::MyEnum::CCC" }
    };
    auto   it  = MyEnumStrings.find(e);
    return it == MyEnumStrings.end() ? "Out of range" : it->second;
}

int main()
{
   std::cout << magic(MyClass::MyEnum::AAA) <<'\n';
   std::cout << magic(MyClass::MyEnum::BBB) <<'\n';
   std::cout << magic(MyClass::MyEnum::CCC) <<'\n';
}

制約

  • 無価値な複製はご遠慮くださいその他の回答または基本リンク
  • マクロベースの回答の肥大化を避けるか、#defineオーバーヘッドを可能な限り最小限に抑えるようにしてください。
  • 手動enum->stringマッピングはしないでください。

あった方がよい

  • enum0以外の数値から始まる値をサポートします
  • enum負の値をサポート
  • enum断片化された価値観をサポートする
  • サポートclass enum(C++11)
  • class enum : <type>任意の許可を持つサポート<type>(C++11)
  • コンパイル時(実行時ではない)の文字列への変換、
    または少なくとも実行時の高速実行(たとえば、std::mapあまり良いアイデアではありません...)
  • constexpr(C++11、その後C++14/17/20で緩和)
  • noexcept(C++11)
  • C++17/C++20フレンドリースニペット

variadic template class考えられるアイデアの 1 つは、C++ コンパイラの機能を使用して、関数に基づくメタプログラミング トリックを使用してコンパイル時に C++ コードを生成することですconstexpr...

ベストアンサー1

マジック列挙体ヘッダーのみのライブラリは、C++17 の列挙型 (文字列へ、文字列から、反復) の静的リフレクションを提供します。

(開示: 私はこのライブラリの作者です。)

#include <magic_enum.hpp>

enum Color { RED = 2, BLUE = 4, GREEN = 8 };

Color color = Color::RED;
auto color_name = magic_enum::enum_name(color);
// color_name -> "RED"

std::string color_name{"GREEN"};
auto color = magic_enum::enum_cast<Color>(color_name)
if (color.has_value()) {
  // color.value() -> Color::GREEN
};

その他の例についてはホームリポジトリを確認してくださいhttps://github.com/Neargye/magic_enum

欠点はどこにあるのでしょうか?

このライブラリは、Clang >= 5、MSVC >= 15.3、および GCC >= 9 で動作するコンパイラ固有のハック ( __PRETTY_FUNCTION__/ベース) を使用します。__FUNCSIG__

列挙値は範囲内である必要があります[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]

  • デフォルトではMAGIC_ENUM_RANGE_MIN = -128、ですMAGIC_ENUM_RANGE_MAX = 128

  • デフォルトですべての列挙型に別の範囲が必要な場合は、マクロを再定義してMAGIC_ENUM_RANGE_MINMAGIC_ENUM_RANGE_MAX

  • MAGIC_ENUM_RANGE_MINは 以下であり0、 は より大きくなければなりませんINT16_MIN

  • MAGIC_ENUM_RANGE_MAXは より大きく0、 より小さくなければなりませんINT16_MAX

  • 特定の列挙型に別の範囲が必要な場合は、必要な列挙型に特殊化 enum_range を追加します。

    #include <magic_enum.hpp>
    
    enum number { one = 100, two = 200, three = 300 };
    
    namespace magic_enum {
    template <>
      struct enum_range<number> {
        static constexpr int min = 100;
        static constexpr int max = 300;
    };
    }
    

おすすめ記事