[Bug libstdc++/121765] `std::formatter` specialization for user-defined type inheriting from `std::formatter<tuple-like>` fails concept `std::formattable` check unexpectedly
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Sep 10 09:50:38 GMT 2025
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121765
--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tomasz Kaminski <tkaminsk@gcc.gnu.org>:
https://gcc.gnu.org/g:ac1665954058f355aab11e1b48b1176c7e0af363
commit r16-3738-gac1665954058f355aab11e1b48b1176c7e0af363
Author: Tomasz KamiÅski <tkaminsk@redhat.com>
Date: Thu Sep 4 13:58:23 2025 +0200
libstdc++: Use _Drop_iter<_CharT> for formattable concept checking
[PR121765]
When producing output, the libstdc++ format implementation only uses
_Sink_iter
specializations. Since users cannot construct basic_format_context, this is
the
only iterator type actually used. The __format_padded helper relies on this
property to efficiently pad sequences from tuples and ranges.
However, the standard's formattable concept requires a generic format
function
in formatters that works with any iterator type. This is intended to
future-proof the implementation by allowing new format_context types.
Previously,
libstdc++ used back_insert_iterator<basic_string<_CharT>> for this purpose.
Normally, concept checks only instantiate function signatures, but with
user-defined formatters and deduced return types, the function body and all
called functions are instantiated. This could trigger a static assertion
error
in the range/tuple formatter that assumed the iterator was a _Sink_iter
(see included test).
This patch resolves the issue by replacing the _Iter_for_t alias with the
internal _Drop_iter. This iterator's sematnics is to drop elements, so
__format_padded can handle it by simply returning the input iterator, which
still produces the required behavior [1].
An alternative of using _Sink_iter was considered but rejected because it
would
allow formatters to pass formattable requirements while only supporting
format_context and wformat_context, which seems counter to the design
intent
(the std/format/formatter/concept.cc fails).
[1] The standard's wording defines format functions as producing an output
representation, but does not explicitly require a formatter to be invoked
for each element. This allows the use of _Drop_iter to pass the concept
check
without generating any output.
PR libstdc++/121765
libstdc++-v3/ChangeLog:
* include/std/format (__format::_Drop_iter): Define.
(_Iter_for_t::type): Change alias to _Drop_iter.
(__format::__format_padded): Return __fc.out() for
_Drop_iter.
* testsuite/std/format/pr121765.cc: New test.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz KamiÅski <tkaminsk@redhat.com>
More information about the Gcc-bugs
mailing list