std::to_underlying(3)
π std::to_underlying(3) β C++ Standard Library
Okay so bestie, we're talking about std::to_underlying, and honestly? It's giving "small function, huge glow-up." It lives in the C++ Standard Library and it does exactly one thing, but it does it flawlessly. π
β¨ NAME β¨
std::to_underlying β yes she's literally named the same thing twice, that's her whole brand, no notes π
π¦ Synopsis π¦
So here's the vibe. She's defined in the header <utility>, and the signature is:
template< class Enum >
constexpr std::underlying_type_t<Enum> to_underlying( Enum e )
(since C++23) β yes, she's a newer girl,ζδ»₯ζ们 stan a modern icon π
noexcept;
And what does she do? She converts an enumeration to its underlying type. That's it. That's the whole thing. She's equivalent to:
return static_cast<std::underlying_type_t<Enum>>(e);
No cap, that's literally the entire implementation and she still ate. π₯
πΈ Parameters πΈ
eβ the enumeration value you want to convert. hand her the enum, she hands you back the int vibes π«Ά
β Return value β
The integer value of the underlying type of Enum, converted from e. So like, if Enum is backed by char, you get a char. If it's backed by std::uint32_t, you get a std::uint32_t. Match made in heaven, no awkward casting situations. π
π§ Notes π§
Here's the actual tea, and it's important: std::to_underlying can be used to avoid converting an enumeration to an integer type other than its underlying type. Like, that's the whole point. Don't just cast to int and hope for the best β she keeps you honest. π
And there's a feature-test macro for her, because of course there is:
- Feature-test macro:
__cpp_lib_to_underlying - Value:
202102L - Std: (C++23)
- Feature:
std::to_underlying
π Example π
// Run this code
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <utility>
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(e))>);
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; // Error: no known conversion
[[maybe_unused]]
std::underlying_type_t<ColorMask> y = std::to_underlying(ColorMask::alpha); // OK
}
π Output:
000000FF
0000FF00
00FF0000
FF000000
Look at those three static_asserts at the top β she proves her type game at compile time, main character energy fr fr. And the color mask bit? Chef's kiss. The direct assignment is a whole error (no known conversion π) but through std::to_underlying? Totally OK. She's the friend who makes the impossible conversion happen. π«Ά
π See also π
underlying_typeβ obtains the underlying integer type for a given enumeration type (C++11) (class template)is_enumβ checks if a type is an enumeration type (C++11) (class template)is_scoped_enumβ checks if a type is a scoped enumeration type (C++23) (class template)
π tiny reminder bestie: this whole page is (since C++23) energy β if you're compiling with something older she simply does not exist yet. Check your standard, iykyk.
That's the whole page, mwah π β sourced from cppreference.com, version 2024.06.10. Go convert some enums, you're gonna slay. β¨ππ¦
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms