On Thu, Nov 13, 2025 at 11:40 PM Jonathan Wakely <[email protected]> wrote: > > And I'm a bit confused here. Why does adding `_Tp = _CharT` prevent > > the overload from appearing for wstream? I'm not sure what I'm > > missing. > > Oops, my suggestion was missing this line before the #endif > > ignore(streamsize __n, char __delim) > > i.e. the __delim should be char, not a deduced _Tp type. > > And so the __enable_if constraint is checking __are_same<_CharT, char> > which is not the same as your original, which was checking that > decltype(__delim) is char. > > The difference is that my suggestion would only enable the function > for std::basic_istream<char, Tr> and not std::basic_istream<wchar_t, > Tr>. >
Thank you for explaining! Just to clarify: When we use char as the parameter type directly, we cannot infer the template argument from the user's input, so it will always default to the default template argument. And we still need an extra _Tp because SFINAE only works in the immediate context? > But please just make it a C++26 change anyway, and then we can just > use requires same_as<_CharT, char> which is exactly the constraint > proposed in P3223R2. > Done. The ambiguous test part has been removed. Do you think we need a compile failure test for this? Yuao
From 6e022cda495dd1b5b1675dc6393b34d506b68d62 Mon Sep 17 00:00:00 2001 From: Yuao Ma <[email protected]> Date: Sat, 15 Nov 2025 23:55:31 +0800 Subject: [PATCH] libstdc++: Implement P3223R2 Making std::istream::ignore less surprising libstdc++-v3/ChangeLog: * include/std/istream: Add a overload for char. * testsuite/27_io/basic_istream/ignore/char/4.cc: New test. --- libstdc++-v3/include/std/istream | 12 +++++++++- .../27_io/basic_istream/ignore/char/4.cc | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream index d5bb1876001..ce7c2268ca4 100644 --- a/libstdc++-v3/include/std/istream +++ b/libstdc++-v3/include/std/istream @@ -42,6 +42,10 @@ #include <ios> #include <ostream> +#if __cplusplus > 202302L +#include <concepts> +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -537,11 +541,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * is extracted); note that this condition will never occur if * @a __delim equals @c traits::eof(). * - * NB: Provide three overloads, instead of the single function + * NB: Provide four overloads, instead of the single function * (with defaults) mandated by the Standard: this leads to a * better performing implementation, while still conforming to * the Standard. */ +#if __cplusplus > 202302L + __istream_type& + ignore(streamsize __n, char __delim) requires same_as<_CharT, char> + { return ignore(__n, traits_type::to_int_type(__delim)); } +#endif + __istream_type& ignore(streamsize __n, int_type __delim); diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc new file mode 100644 index 00000000000..8b092ed5180 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc @@ -0,0 +1,22 @@ +// { dg-do run { target c++26 } } +#include <testsuite_hooks.h> + +#include <istream> +#include <sstream> +#include <string> + +void test01() { + std::istringstream in("\xF0\x9F\xA4\xA1 Clown Face"); + in.ignore(100, '\xA1'); + VERIFY(in.gcount() == 4); + VERIFY(in.peek() == ' '); + + std::string str; + in >> str; + VERIFY(str == "Clown"); +} + +int main() { + test01(); + return 0; +} -- 2.51.1
