はじめに
プログラミング言語C++ではenumが使えます。 しかしenumは日本語文字列が使えません。
enum class hoge { "青", "黄", "赤" }; // NG
日本語で書くにはどうするか。 ということで、以下のようにしてみました。
#include <algorithm> #include <array> #include <cassert> #include <cstddef> #include <string_view> #include <utility> class master { using value_type = std::pair<std::string_view, int>; // 装備名とIDのマスタデータ // このマスタデータは、実行時に持ち込まない static constexpr auto mst = std::array<value_type, 6>{{ {"10.5cm連装砲", 160}, {"10cm連装高角砲", 3}, {"10cm連装高角砲(砲架)", 71}, {"10cm連装高角砲+高射装置", 122}, {"10cm連装高角砲改+増設機銃", 275}, {"10cm連装高角砲群 集中配備", 464}, // ... }}; // マスタデータは二分探索できるようにソート済み static_assert(std::ranges::is_sorted(mst, {}, &value_type::first)); public: // 装備名をキーにIDを得る static consteval int id(std::string_view name) { const auto itr = std::ranges::lower_bound(mst, name, {}, &value_type::first); // これらの表明は、constevalの実行時すなわちコンパイル時に行われる assert(itr != mst.end()); assert(itr->first == name); // 引数の装備名がマスタに存在する場合にのみIDを返す // 存在しなければ上記assertによってコンパイルエラー return itr->second; } }; namespace literals { consteval int operator""_id(const char* str, std::size_t size) { return master::id(std::string_view{str, size}); } } // namespace literals int main() { // static_assert(master::id("10.5cm連装砲") == 160); { using literals::operator""_id; static_assert("10cm連装高角砲群 集中配備"_id == 464); } { using literals::operator""_id; // static_assert("100km連装砲"_id == 100); } }