[Bug libstdc++/126716] New: under _GLIBCXX_DEBUG, std::erase_if on unordered container with transparent comparator fails to compile in C++23

"sberg.fun at gmail dot com via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126716

            Bug ID: 126716
           Summary: under _GLIBCXX_DEBUG, std::erase_if on unordered
                    container with transparent comparator fails to compile
                    in C++23
           Product: gcc
           Version: 16.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sberg.fun at gmail dot com
  Target Milestone: ---

At least with
gcc-c++-16.1.1-2.fc44.x86_64/libstdc++-devel-16.1.1-2.fc44.x86_64, as well as
with a recent local GCC 17 trunk installation,

```
$ cat test.cc
#include <functional>
#include <unordered_set>
struct H {
    using is_transparent = void;
    std::size_t operator()(int) const noexcept { return 0; }
};
int main() {
    std::unordered_set<int, H, std::equal_to<>> s;
    std::erase_if(s, [](int){ return true; });
}
```

```
$ g++ -fsyntax-only -std=c++23 -D_GLIBCXX_DEBUG test.cc
In file included from /usr/include/c++/16/unordered_map:45,
                 from /usr/include/c++/16/functional:80,
                 from test.cc:1:
/usr/include/c++/16/bits/erase_if.h: In instantiation of ‘typename
_Container::size_type std::__detail::__erase_nodes_if(_Container&,
_UnsafeContainer&, _Predicate) [with _Container =
std::__debug::unordered_set<int, H, std::equal_to<void> >; _UnsafeContainer =
std::__cxx1998::unordered_set<int, H, std::equal_to<void>, std::allocator<int>
>; _Predicate = main()::<lambda(int)>; typename _Container::size_type = long
unsigned int]’:
/usr/include/c++/16/debug/unordered_set:1676:40:   required from ‘typename
std::__debug::unordered_set<_Key, _Hash, _Pred, _Allocator>::size_type
std::erase_if(__debug::unordered_set<_Tp, _Hash, _Pred, _Allocator>&,
_Predicate) [with _Key = int; _Hash = H; _CPred = equal_to<void>; _Alloc =
allocator<int>; _Predicate = main()::<lambda(int)>; typename
__debug::unordered_set<_Key, _Hash, _Pred, _Allocator>::size_type = long
unsigned int]’
 1676 |     { return __detail::__erase_nodes_if(__cont, __cont._M_base(),
__pred); }
      |             
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cc:9:18:   required from here
    9 |     std::erase_if(s, [](int){ return true; });
      |     ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/16/bits/erase_if.h:81:24: error: no match for ‘operator=’
(operand types are ‘std::__detail::_Node_iterator<int, true, false>’ and
‘std::__debug::unordered_set<int, H, std::equal_to<void> >::size_type’ {aka
‘long unsigned int’})
   81 |                 __iter = __cont.erase(__iter);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
  • there are 2 candidates
In file included from /usr/include/c++/16/bits/hashtable.h:37,
                 from /usr/include/c++/16/bits/unordered_map.h:33,
                 from /usr/include/c++/16/unordered_map:43:
    • candidate 1: ‘constexpr std::__detail::_Node_iterator<int, true, false>&
std::__detail::_Node_iterator<int, true, false>::operator=(const
std::__detail::_Node_iterator<int, true, false>&)’
      /usr/include/c++/16/bits/hashtable_policy.h:401:12:
        401 |     struct _Node_iterator
            |            ^~~~~~~~~~~~~~
      • no known conversion for argument 1 from
‘std::__debug::unordered_set<int, H, std::equal_to<void> >::size_type’ {aka
‘long unsigned int’} to ‘const std::__detail::_Node_iterator<int, true,
false>&’
    • candidate 2: ‘constexpr std::__detail::_Node_iterator<int, true, false>&
std::__detail::_Node_iterator<int, true,
false>::operator=(std::__detail::_Node_iterator<int, true, false>&&)’
      • no known conversion for argument 1 from
‘std::__debug::unordered_set<int, H, std::equal_to<void> >::size_type’ {aka
‘long unsigned int’} to ‘std::__detail::_Node_iterator<int, true, false>&&’
```

fails (and works if you either drop -D_GLIBCXX_DEBUG or go from -std=c++23 down
to -std=c++20).
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.