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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
          Component|c++                         |libstdc++

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Further reduced:

template<typename _Tp>
  _Tp&& declval() noexcept;

template<typename Arg>
  struct function
  {
    template<typename Functor,
             typename = decltype( declval<Functor&>()(declval<Arg>()) )>
      function(Functor) { }

    function() { }

    bool operator()(Arg) const;
  };


template<typename Compare>
  struct Iter_comp
  {
    Compare m_comp;

    Iter_comp(Compare comp)
      : m_comp(comp)
    { }

    template<typename Iterator>
#ifndef OK
      constexpr
#endif
      bool
      operator()(Iterator it) const
      { return m_comp(*it); }
  };

using F = function<int>;
F f;
Iter_comp<F> c{ f };
auto c2 = c;


GCC says:

f.cc: In instantiation of ‘constexpr bool
Iter_comp<Compare>::operator()(Iterator) const [with Iterator = int; Compare =
function<int>]’:
f.cc:8:52:   required by substitution of ‘template<class Functor, class>
function<Arg>::function(Functor) [with Functor = Iter_comp<function<int> >;
<template-parameter-1-2> = <missing>]’
f.cc:38:11:   required from here
f.cc:32:23: error: invalid type argument of unary ‘*’ (have ‘int’)
       { return m_comp(*it); }
                       ^

and Clang says:

f.cc:32:23: error: indirection requires pointer operand ('int' invalid)
      { return m_comp(*it); }
                      ^~~
f.cc:8:35: note: in instantiation of function template specialization
'Iter_comp<function<int> >::operator()<int>' requested here
             typename = decltype( declval<Functor&>()(declval<Arg>()) )>
                                  ^
f.cc:9:7: note: in instantiation of default argument for
'function<Iter_comp<function<int> > >' required here
      function(Functor) { }
      ^~~~~~~~
f.cc:38:11: note: while substituting deduced template arguments into function
template 'function' [with Functor = Iter_comp<function<int> >, $1 = (no value)]
auto c2 = c;
          ^
1 error generated.



What I don't understand is why function<int>::function<Comp_iter<function<int>>
ever gets considered for overload resolution. Where does that come from and
why?


Anyway, it seems we can fix the library by constraining
_Iter_comp_iter::operator()


    template<typename Iterator, typename =
decltype(declval<Compare&>()(*declval<Iterator>()))>
#ifndef OK
      constexpr
#endif
      bool
      operator()(Iterator it) const
      { return m_comp(*it); }

That prevents it being instantiated as a possible argument to std::function.

Changing component back to libstdc++

Reply via email to