diff --git a/libstdc++-v3/include/std/forward_list b/libstdc++-v3/include/std/forward_list index 6c5ad1195db..166fdb04242 100644 --- a/libstdc++-v3/include/std/forward_list +++ b/libstdc++-v3/include/std/forward_list @@ -83,8 +83,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename forward_list<_Tp, _Alloc>::size_type erase(forward_list<_Tp, _Alloc>& __cont, const _Up& __value) { - using __elem_type = typename forward_list<_Tp, _Alloc>::value_type; - return std::erase_if(__cont, [&](__elem_type& __elem) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4135. helper lambda of std::erase for list should specify return type + return std::erase_if(__cont, [&](const auto& __elem) -> bool { return __elem == __value; }); } diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list index 51f1bc079cc..170499d65f7 100644 --- a/libstdc++-v3/include/std/list +++ b/libstdc++-v3/include/std/list @@ -107,8 +107,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename list<_Tp, _Alloc>::size_type erase(list<_Tp, _Alloc>& __cont, const _Up& __value) { - using __elem_type = typename list<_Tp, _Alloc>::value_type; - return std::erase_if(__cont, [&](__elem_type& __elem) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4135. helper lambda of std::erase for list should specify return type + return std::erase_if(__cont, [&](const auto& __elem) -> bool { return __elem == __value; }); } diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc b/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc index 37e50203959..1ec11de6e36 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/erasure.cc @@ -53,6 +53,28 @@ test02() VERIFY( num == 0 ); } +// LWG 4135. +// The helper lambda of std::erase for list should specify return type as bool +void +test_lwg4135() +{ + struct Bool { + Bool() = default; + Bool(const Bool&) = delete; + operator bool() const { return false; } + }; + + static Bool b; + + struct Int { + Bool& operator==(Int) const { return b; } + void operator==(Int) = delete; + }; + + std::forward_list l; + std::erase(l, Int{}); +} + int main() { diff --git a/libstdc++-v3/testsuite/23_containers/list/erasure.cc b/libstdc++-v3/testsuite/23_containers/list/erasure.cc index 1a33eca77c2..9f4f8536fe6 100644 --- a/libstdc++-v3/testsuite/23_containers/list/erasure.cc +++ b/libstdc++-v3/testsuite/23_containers/list/erasure.cc @@ -52,6 +52,28 @@ test02() VERIFY( num == 0 ); } +// LWG 4135. +// The helper lambda of std::erase for list should specify return type as bool +void +test_lwg4135() +{ + struct Bool { + Bool() = default; + Bool(const Bool&) = delete; + operator bool() const { return false; } + }; + + static Bool b; + + struct Int { + Bool& operator==(Int) const { return b; } + void operator==(Int) = delete; + }; + + std::list l; + std::erase(l, Int{}); +} + int main() {