天津网站制作福州,网络维护电话,公司网站费用计入什么科目,佛山网络公司推荐首先#xff0c;有两种方法#xff1a;使用命名空间和字符串常量与使用 enum class 和辅助函数。
表格直观展示
特性使用命名空间和字符串常量使用 enum class 和辅助函数类型安全性低 - 编译器无法检查字符串有效性#xff0c;运行时发现错误高 - 编译期类型检查#xf…首先有两种方法使用命名空间和字符串常量与使用 enum class 和辅助函数。
表格直观展示
特性使用命名空间和字符串常量使用 enum class 和辅助函数类型安全性低 - 编译器无法检查字符串有效性运行时发现错误高 - 编译期类型检查非法类型在编译期即可发现性能低 - 字符串比较时间复杂度为 O(n)逐字符比较有开销高 - 枚举值比较时间复杂度为 O(1)查找效率高平均查找为 O(1)可维护性中 - 易于理解和使用但字符串容易拼写错误高 - 易读易维护枚举类型和映射关系可以方便管理和扩展代码简洁性中 - 可能需要反复访问命名空间中的字符串常量高 - 代码简洁且易读枚举结合辅助函数方便处理安全性中 - 字符串误输入导致运行时错误高 - 通过类型检查避免运行时崩溃易用性中 - 需要记住和管理字符串常量容易犯拼写错误高 - 枚举值可以通过智能提示和自动补全大幅减少错误
代码展示
使用命名空间和字符串常量
优点
直观和易于理解字符串表示类型或状态非常直观容易理解和使用。与外部系统交互方便许多外部系统或配置文件使用字符串表示状态或类型直接使用字符串便于与这些系统交互。
缺点
类型不安全任何字符串都可以传入编译器无法检查其有效性拼写错误会导致运行时错误。性能开销较大字符串比较和逐字符检查的时间复杂度为 O(n)性能较低尤其是在处理长字符串时。可维护性差字符串常量需要在代码中多次引用拼写错误不易发现维护困难。
namespace ContainerType {const std::string SimpleView SimpleView;const std::string SimpleViewPage SimpleViewPage;const std::string ListView ListView;const std::string ListViewPage ListViewPage;const std::string Dialog Dialog;
}void handleContainerType(const std::string type) {if (type ContainerType::SimpleView) {std::cout Handling SimpleView std::endl;} else if (type ContainerType::SimpleViewPage) {std::cout Handling SimpleViewPage std::endl;} else if (type ContainerType::ListView) {std::cout Handling ListView std::endl;} else if (type ContainerType::ListViewPage) {std::cout Handling ListViewPage std::endl;} else if (type ContainerType::Dialog) {std::cout Handling Dialog std::endl;} else {std::cout Unknown type std::endl;}
}使用 enum class 和辅助函数
优点
类型安全编译器进行类型检查非法类型在编译期即可发现避免运行时错误。性能高效枚举值比较时间复杂度为 O(1)使用哈希表进行字符串到枚举的映射查找平均为 O(1)高效。代码可维护性高枚举值清晰明了降低拼写错误风险方便代码维护。易于扩展可以方便地添加新的枚举值和映射关系。
缺点
稍微复杂需要维护枚举和映射关系初次使用时可能需要更多理解。
enum class ContainerType {SimpleView,SimpleViewPage,ListView,ListViewPage,Dialog,Unknown
};// 辅助函数字符串 - ContainerType
ContainerType stringToContainerType(const std::string typeStr) {static const std::unordered_mapstd::string, ContainerType stringToEnumMap {{SimpleView, ContainerType::SimpleView},{SimpleViewPage, ContainerType::SimpleViewPage},{ListView, ContainerType::ListView},{ListViewPage, ContainerType::ListViewPage},{Dialog, ContainerType::Dialog}};auto it stringToEnumMap.find(typeStr);if (it ! stringToEnumMap.end()) {return it-second;}return ContainerType::Unknown;
}void handleContainerType(ContainerType type) {switch (type) {case ContainerType::SimpleView:std::cout Handling SimpleView std::endl;break;case ContainerType::SimpleViewPage:std::cout Handling SimpleViewPage std::endl;break;case ContainerType::ListView:std::cout Handling ListView std::endl;break;case ContainerType::ListViewPage:std::cout Handling ListViewPage std::endl;break;case ContainerType::Dialog:std::cout Handling Dialog std::endl;break;default:std::cout Unknown type std::endl;break;}
}int main() {ContainerType type ContainerType::SimpleView;handleContainerType(type);type stringToContainerType(Dialog);handleContainerType(type);return 0;
}开源项目magic_enum
magic_enum 是一个 C17 的头文件库提供了对枚举的静态反射功能。它允许你在不使用宏或样板代码的情况下轻松地将枚举类型与字符串进行转换并实现一系列有关枚举的高效操作。有如下类
enum class Color { RED 1, BLUE, GREEN, NONE };
功能描述示例代码枚举值转字符串将枚举值转换为字符串auto color_name magic_enum::enum_name(color);字符串转枚举值将字符串转换为枚举值不区分大小写、二元谓词比较auto color magic_enum::enum_castColor(color_name);auto color magic_enum::enum_castColor(green, magic_enum::case_insensitive);auto color magic_enum::enum_castColor(green, [](char lhs, char rhs) { return std::tolower(lhs) std::tolower(rhs); });整数转枚举值将整数转换为枚举值auto color magic_enum::enum_castColor(color_integer);通过索引访问枚举值根据索引获取枚举值Color color magic_enum::enum_valueColor(i);获取枚举值序列获取所有枚举值的序列constexpr auto colors magic_enum::enum_valuesColor();获取枚举元素数量获取枚举的元素个数constexpr std::size_t color_count magic_enum::enum_countColor();获取枚举值的整数获取枚举值对应的整数auto color_integer magic_enum::enum_integer(color);auto color_integer magic_enum::enum_underlying(color);获取枚举名称序列获取所有枚举值的名称序列constexpr auto color_names magic_enum::enum_namesColor();获取枚举条目序列获取所有枚举值和名称的序列constexpr auto color_entries magic_enum::enum_entriesColor();检查枚举是否包含某个值检查枚举类型是否包含某个值magic_enum::enum_contains(Color::GREEN);magic_enum::enum_containsColor(2);magic_enum::enum_containsColor(GREEN);获取枚举值的索引获取枚举值在序列中的索引constexpr auto color_index magic_enum::enum_index(Color::BLUE);枚举的位运算支持对枚举类型进行位运算using namespace magic_enum::bitwise_operators; Flags flags Flags::A标志枚举支持对标志枚举进行特殊处理template struct magic_enum::customize::enum_rangeDirections { static constexpr bool is_flags true; }; auto name magic_enum::enum_flags_name(Directions::Up枚举类型的名称获取枚举类型的名称auto type_name magic_enum::enum_type_namedecltype(color)();ENUM 类型换为在IO流的操作符为枚举添加 ostream 和 istream 的支持using magic_enum::iostream_operators::operator;using magic_enum::iostream_operators::operator;检查是否为无范围枚举判断类型是否为无范围枚举magic_enum::is_unscoped_enumcolor::value;magic_enum::is_unscoped_enum_vcolor;检查是否为范围枚举判断类型是否为范围枚举magic_enum::is_scoped_enumdirection::value;magic_enum::is_scoped_enum_vdirection;Bitwise 操作符为枚举类型提供位操作符using namespace magic_enum::bitwise_operators; Flags flags Flags::A静态存储枚举变量到字符串更轻量的编译时间和不限于 enum_range 的限制constexpr auto color_name magic_enum::enum_namecolor();
一个简单的示例
#include iostream
#include string
#include magic_enum.hppenum class Color { RED 1, BLUE, GREEN, NONE };int main() {// 枚举值转字符串Color color1 Color::RED;std::cout Color 1: magic_enum::enum_name(color1) std::endl;// 字符串转枚举值std::string color_name{GREEN};auto color2 magic_enum::enum_castColor(color_name);if (color2.has_value()) {std::cout Color 2: magic_enum::enum_name(color2.value()) std::endl;}return 0;
}遇到的问题
main.cpp:3:10: fatal error: magic_enum.hpp file not found #include magic_enum.hpp ^~~~~~~~~~~~~~~~ 1 error generated.
解决方法
下载并包含 magic_enum 库。你可以从 magic_enum 的 GitHub 页面上下载最新的版本GitHub - Neargye/magic_enum: Static reflection for enums (to string, from string, iteration) for modern C, work with any enum type without any macro or boilerplate code将 magic_enum.hpp 头文件放在你的项目的合适目录中例如 include 目录。编译
g -stdc17 -Iinclude main.cpp -o main如果你使用 CMake 进行项目构建可以通过 FetchContent 将 megic_enum 集成到你的项目中。 cmake_minimum_required(VERSION 3.11)project(MyProject)include(FetchContent)FetchContent_Declare(magic_enumGIT_REPOSITORY https://github.com/Neargye/magic_enum.gitGIT_TAG v0.7.3)FetchContent_MakeAvailable(magic_enum)add_executable(main src/main.cpp)target_link_libraries(main PRIVATE magic_enum::magic_enum)模拟实现magic_enum
#include array
#include string
#include utility
#include string_viewtemplate typename E, E V
constexpr auto PrettyName()
{std::string_view name{__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2};name.remove_prefix(name.find_last_of( ) 1);if (name.front() () name.remove_prefix(name.size());return name;
}template typename E, E V
constexpr bool IsValidEnum()
{return !PrettyNameE, V().empty();
}template int... Seq
constexpr auto MakeIntegerSequence(std::integer_sequenceint, Seq...)
{return std::integer_sequenceint, (Seq)...();
}constexpr auto NormalIntegerSequence MakeIntegerSequence(std::make_integer_sequenceint, 32());template typename E, int... Seq
constexpr size_t GetEnumSize(std::integer_sequenceint, Seq...)
{constexpr std::arraybool, sizeof...(Seq) valid{IsValidEnumE, static_castE(Seq)()...};constexpr std::size_t count [](decltype((valid)) v) constexpr noexcept-std::size_t{auto cnt std::size_t{0};for (auto b : v) if (b) cnt;return cnt;}(valid);return count;
}template typename E, int... Seq
constexpr auto GetAllValidValues(std::integer_sequenceint, Seq...)
{constexpr std::size_t count sizeof...(Seq);constexpr std::arraybool, count valid{IsValidEnumE, static_castE(Seq)()...};constexpr std::arrayint, count seq{Seq...};std::arrayint, GetEnumSizeE(NormalIntegerSequence) values{};for (std::size_t i 0, v 0; i count; i) if (valid[i]) values[v] seq[i];return values;
}template typename E, int... Seq
constexpr auto GetAllValidNames(std::integer_sequenceint, Seq...)
{constexpr std::arraystd::string_view, sizeof...(Seq) names{PrettyNameE, static_castE(Seq)()...};std::arraystd::string_view, GetEnumSizeE(NormalIntegerSequence) validNames{};for (std::size_t i 0, v 0; i names.size(); i) if (!names[i].empty()) validNames[v] names[i];return validNames;
}template typename E
constexpr std::string_view Enum2String(E V)
{constexpr auto names GetAllValidNamesE(NormalIntegerSequence);constexpr auto values GetAllValidValuesE(NormalIntegerSequence);constexpr auto size GetEnumSizeE(NormalIntegerSequence);for (size_t i 0; i size; i) if (static_castint(V) values[i]) return names[i];return std::to_string(static_castint(V));
}#include myenum.h
#include iostreamenum class Color
{RED,GREEN,BLUE,
};int main()
{Color c Color::BLUE;std::cout Enum2String(c) std::endl;return 0;
}