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

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Yes, and so do 4.8 and 4.9 for this reduced form with no library dependencies.
This fails with -std=c++11 but compiles OK with -std=c++11 -DOK.

EDG accepts it without -DOK


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

template<typename> struct function;

template<typename _Res, typename... _ArgTypes>
  struct function<_Res(_ArgTypes...)>
  {
    template<typename _Functor,
             typename = decltype( declval<_Functor&>()(declval<_ArgTypes>()...)
)>
      function(_Functor) { }

    function() { }

    _Res operator()(_ArgTypes...) const;
  };


  template<typename _Compare>
    struct _Iter_comp_iter
    {
      _Compare _M_comp;

      _Iter_comp_iter(_Compare __comp)
        : _M_comp(__comp)
      { }

      template<typename _Iterator1, typename _Iterator2>
#ifndef OK
        constexpr
#endif
        bool
        operator()(_Iterator1 __it1, _Iterator2 __it2)
        { return bool(_M_comp(*__it1, *__it2)); }
    };

using F = function<bool (int, int)>;
F f;
_Iter_comp_iter<F> c{ f };
auto c2 = c;



f.cc: In instantiation of ‘constexpr bool
_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) const [with
_Iterator1 = int; _Iterator2 = int; _Compare = function<bool(int, int)>]’:
f.cc:10:54:   required by substitution of ‘template<class _Functor, class>
function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor =
_Iter_comp_iter<function<bool(int, int)> >; <template-parameter-1-2> =
<missing>]’
f.cc:40:11:   required from here
f.cc:34:31: error: invalid type argument of unary ‘*’ (have ‘int’)
         { return bool(_M_comp(*__it1, *__it2)); }
                               ^
f.cc:34:39: error: invalid type argument of unary ‘*’ (have ‘int’)
         { return bool(_M_comp(*__it1, *__it2)); }
                                       ^


So the regression is in the library adding 'constexpr' to _Iter_comp_iter, not
a regression in the compiler, although the problem may be inherent to the
SFINAE constraints in std::function.


It seems that defining the implicit copy constructor of _Iter_comp_iter
performs overload resolution on the function(_Functor) constructor, which
checks the SFINAE constraint, which instantiates
_Iter_comp_iter::operator()<int, int> and that fails if it's constexpr, but
compiles OK otherwise.

Reply via email to