https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102863

            Bug ID: 102863
           Summary: Optional monadic ops should not be constrained
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rs2740 at gmail dot com
  Target Milestone: ---

It's important that these are not constrained with invocable; that constraint
can trigger hard errors during overload resolution. For instance:

void f(int&);

int main() {
    std::optional<int> x;
    x.transform([](auto& y) { f(y); return 42; });
}

<source>: In instantiation of 'main()::<lambda(auto:3&)> [with auto:3 = const
int]':
/opt/compiler-explorer/gcc-trunk-20211020/include/c++/12.0.0/type_traits:2565:26:
  required by substitution of 'template<class _Fn, class ... _Args> static
std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)),
std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn =
main()::<lambda(auto:3&)>; _Args = {const int&}]'
/opt/compiler-explorer/gcc-trunk-20211020/include/c++/12.0.0/type_traits:2576:55:
  required from 'struct std::__result_of_impl<false, false,
main()::<lambda(auto:3&)>, const int&>'
/opt/compiler-explorer/gcc-trunk-20211020/include/c++/12.0.0/type_traits:3038:12:
  recursively required by substitution of 'template<class _Result, class _Ret>
struct std::__is_invocable_impl<_Result, _Ret, true, std::__void_t<typename
_CTp::type> > [with _Result = std::__invoke_result<main()::<lambda(auto:3&)>,
const int&>; _Ret = void]'
/opt/compiler-explorer/gcc-trunk-20211020/include/c++/12.0.0/type_traits:3038:12:
  required from 'struct std::is_invocable<main()::<lambda(auto:3&)>, const
int&>'
/opt/compiler-explorer/gcc-trunk-20211020/include/c++/12.0.0/type_traits:3286:71:
  required from 'constexpr const bool
std::is_invocable_v<main()::<lambda(auto:3&)>, const int&>'
/opt/compiler-explorer/gcc-trunk-20211020/include/c++/12.0.0/concepts:336:25:  
required by substitution of 'template<class _Fn>  requires  invocable<_Fn,
const _Tp&> constexpr auto std::optional<int>::transform(_Fn&&) const & [with
_Fn = int]'
<source>:7:16:   required from here
<source>:7:32: error: binding reference of type 'int&' to 'const int' discards
qualifiers
    7 |     x.transform([](auto& y) { f(y); return 42; });
      |                               ~^~~
<source>:3:8: note:   initializing argument 1 of 'void f(int&)'
    3 | void f(int&);
      |        ^~~~

Reply via email to