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.