P3876R1 - Extending support to more character types WG21
Posted by u/mailing_watcher_2024 · 7 hr. ago

Authors: Jan Schultke, Peter Bindels
Document: P3876R1
Date: 2026-02-22
Target: SG16
Link: wg21.link/p3876r1

Jan Schultke and Peter Bindels propose extending std::to_chars and std::from_chars to work with char8_t, char16_t, char32_t, and wchar_t - not just char. The motivation is straightforward: if you're building a JSON parser with char8_t strings, you currently can't convert numbers without going through char first. Since every digit and sign that charconv touches is Basic Latin (ASCII), supporting other character types is mechanically simple.

The main design challenge is avoiding overload explosion. Adding non-template overloads for every character type times every arithmetic type would give you around 110 functions, so the paper uses function templates constrained by a character-type concept instead. The existing result types (to_chars_result, from_chars_result) can't be templated without breaking ABI, so new per-character-type result structs are introduced along with alias templates.

SG16 reviewed R0 in early 2026 with consensus in favor, though char16_t support only got weak consensus. R1 incorporates that feedback with minor fixes and rebased wording.

▲ 34 points (78% upvoted) · 8 comments
sorted by: best
u/deprecate_everything 47 points 6 hr. ago
wchar_t support is slightly less motivated, and wchar_t isn't used much outside of Windows environments

The year is 2026 and we're standardizing wchar_t overloads for charconv. I love this timeline.

u/daily_LPCWSTR 14 points 5 hr. ago

Some of us deal with Win32 APIs every single day. Being able to to_chars directly into a wchar_t buffer instead of converting through char and then MultiByteToWideChar is genuinely useful. Not everything is Linux.

u/just_ship_utf8 38 points 5 hr. ago

Finally. I've been doing reinterpret_cast<const char*> on my u8string_view buffers before feeding them to from_chars for two years now. It works but it feels deeply wrong.

u/format_string_refugee 22 points 4 hr. ago

Now do std::format with char8_t format strings. And std::print(u8""). Please. I'm begging.

u/reads_the_minutes 18 points 3 hr. ago

SG16 already polled on this during Q1 2026. Consensus was clear for to_chars, from_chars, char8_t, char32_t, and wchar_t. But char16_t only got weak consensus - 4 strongly in favor, 0 in favor, 4 neutral, 1 against.

I wouldn't be surprised if char16_t gets pushed back when this reaches LEWG. The motivation for it basically boils down to "well, if we're doing the other Unicode types, might as well." That's not exactly compelling when it adds more overloads to an already enormous surface area.

The SG16 issue has been open since 2018. Eight years from "paper needed" label to R1. Committee speed is something else.

u/charconv_intern 11 points 2 hr. ago
If we also added a non-template overload for each character type, this would result in an absurd overload set of 110 functions

The function-template approach is fine, but the result type situation is going to confuse people. You end up with to_chars_result, u8to_chars_result, u16to_chars_result, u32to_chars_result, wto_chars_result, and then the same five for from_chars. Ten new types because ABI prevents templating the existing ones.

The to_chars_result_t<T> alias helps but it's the kind of thing that makes teaching charconv harder. "What does to_chars return?" "Depends on the character type. Let me show you the alias template."

Best part of the paper is the implementation survey. All three major standard libraries already have the conversion logic in internal templates. This is essentially just exposing what already exists with a public API. The static_cast<charT>('+') fix for libc++ is about as complex as it gets.

u/encoding_pessimist 6 points 1 hr. ago

The real problem isn't that to_chars doesn't support char8_t. The real problem is that nothing in the standard library accepts char8_t in a useful way. You can't construct a std::string from a u8 literal without a cast. You can't pass u8"hello" to std::cout. Adding char8_t to charconv is nice but it's like installing a new faucet in a house that has no plumbing.

u/just_ship_utf8 5 points 42 min. ago

This is the plumbing. The paper literally says char8_t to_chars is a prerequisite for char8_t std::format which is a prerequisite for char8_t std::print. You have to start somewhere.