欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > 探索 C++23 std::to_underlying:枚举底层值获取的利器

探索 C++23 std::to_underlying:枚举底层值获取的利器

2025/5/4 13:50:33 来源:https://blog.csdn.net/Z_oioihoii/article/details/147688136  浏览:    关键词:探索 C++23 std::to_underlying:枚举底层值获取的利器

文章目录

    • 引言
    • 基本概念
    • 作用
    • 使用示例
    • 与之前方法的对比
    • 在 C++23 中的意义
    • 总结

引言

在 C++ 的发展历程中,每一个新版本都带来了许多令人期待的新特性和改进,以提升代码的安全性、可读性和可维护性。C++23 作为其中的一个重要版本,也不例外。其中,std::to_underlying 这个工具函数便是 C++23 为开发者带来的一个实用礼物,它主要用于获取枚举(enum)的底层值。本文将深入探讨 std::to_underlying 的相关内容,包括其基本概念、作用、使用示例、与之前方法的对比以及在 C++23 中的意义。

基本概念

std::to_underlying 是 C++23 标准库中新增的一个实用工具函数,定义于头文件 <utility> 中。其函数原型如下:

emplate< class Enum >
constexpr std::underlying_type_t< Enum> to_underlying( Enum e ) noexcept ;

该函数的作用是将枚举类型转换为其底层类型,等价于 return static_cast<std::underlying_type_t<Enum>>(e);。这里的 Enum 是枚举类型,e 是要转换的枚举值,函数返回的是 Enum 的底层类型的整数值,从 e 转换而来。

作用

在实际编程中,我们经常会遇到需要将枚举值转换为其底层整数类型的情况。例如,当我们需要与一些无类型的 API 进行交互时,或者在进行日志记录、流操作等场景下,都可能需要获取枚举的底层值。在 std::to_underlying 出现之前,开发者通常会使用 static_cast 来完成这个转换,但这种方式存在一些问题。

使用 static_cast 进行枚举到其底层类型的转换,会使代码的可读性和可维护性变差。因为在代码中,static_cast 看起来就像普通的类型转换,很难快速识别出这是一个从强类型枚举到其底层值的转换。而且,当枚举类型的底层类型发生变化时(例如从有符号类型变为无符号类型),使用 static_cast 的代码可能会出现潜在的错误。而 std::to_underlying 的出现,正是为了解决这些问题,它提供了一种更安全、更清晰的方式来获取枚举的底层值。

使用示例

下面通过几个具体的示例来展示 std::to_underlying 的使用方法。

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <utility>// 示例 1:不同枚举类型的底层类型验证
enum class E1 : char { e };
static_assert(std::is_same_v<char, decltype(std::to_underlying(E1::e))>);enum struct E2 : long { e };
static_assert(std::is_same_v<long, decltype(std::to_underlying(E2::e))>);enum E3 : unsigned { e };
static_assert(std::is_same_v<unsigned, decltype(std::to_underlying(E3::e))>);// 示例 2:实际输出枚举的底层值
int main()
{enum class ColorMask : std::uint32_t{red = 0xFF, green = (red << 8), blue = (green << 8), alpha = (blue << 8)};std::cout << std::hex << std::uppercase << std::setfill('0')<< std::setw(8) << std::to_underlying(ColorMask::red) << '\n'<< std::setw(8) << std::to_underlying(ColorMask::green) << '\n'<< std::setw(8) << std::to_underlying(ColorMask::blue) << '\n'<< std::setw(8) << std::to_underlying(ColorMask::alpha) << '\n';// 编译错误示例,不能直接将枚举赋值给底层类型变量// std::underlying_type_t<ColorMask> x = ColorMask::alpha; // 正确示例,使用 std::to_underlying 进行转换[[maybe_unused]]std::underlying_type_t<ColorMask> y = std::to_underlying(ColorMask::alpha); return 0;
}

在上述代码中,示例 1 通过 static_assert 验证了不同枚举类型使用 std::to_underlying 转换后的底层类型是否正确。示例 2 则实际输出了 ColorMask 枚举的各个值的底层类型,并且展示了直接将枚举赋值给底层类型变量会导致编译错误,而使用 std::to_underlying 则可以正确进行转换。

与之前方法的对比

std::to_underlying 出现之前,开发者通常会使用 static_cast 来将枚举转换为其底层类型。例如:

enum class MyEnum : int { Value1, Value2 };
int underlyingValue = static_cast<int>(MyEnum::Value1);

这种方式虽然可以实现功能,但存在一些缺点。首先,代码的可读性较差,从 static_cast 的使用中很难一眼看出这是在进行枚举到其底层类型的转换。其次,当枚举的底层类型发生变化时,需要手动修改 static_cast 中的目标类型,否则可能会导致潜在的错误。

而使用 std::to_underlying 则可以避免这些问题。std::to_underlying 明确地表示了这是一个将枚举转换为其底层类型的操作,提高了代码的可读性。并且,无论枚举的底层类型如何变化,std::to_underlying 都能正确工作,无需手动修改代码。例如:

enum class MyEnum : int { Value1, Value2 };
int underlyingValue = std::to_underlying(MyEnum::Value1);

即使 MyEnum 的底层类型从 int 变为其他类型,上述代码仍然可以正常工作。

在 C++23 中的意义

std::to_underlying 的引入是 C++ 语言不断发展和完善的体现。它符合现代 C++ 注重代码安全性、可读性和可维护性的设计理念。在 C++23 中,std::to_underlying 作为标准库的一部分,为开发者提供了一个统一、规范的方式来处理枚举到其底层类型的转换。

随着 C++ 标准的不断演进,枚举类型在 C++ 中的应用也越来越广泛。从 C++11 引入的枚举类(enum class)解决了传统枚举的命名冲突和隐式转换问题,到 C++17 允许使用大括号初始化基础类型,再到 C++20 引入的 using enum 语法,枚举类型的功能不断得到增强。而 std::to_underlying 的出现,进一步完善了枚举类型的使用场景,使得开发者在处理枚举时更加方便和安全。

总结

std::to_underlying 是 C++23 为开发者带来的一个实用工具函数,它为获取枚举的底层值提供了一种更安全、更清晰的方式。通过使用 std::to_underlying,可以提高代码的可读性和可维护性,避免因枚举底层类型变化而带来的潜在错误。在实际开发中,当需要将枚举转换为其底层类型时,建议优先使用 std::to_underlying。相信随着 C++23 的逐渐普及,std::to_underlying 会在更多的项目中得到广泛应用。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词