https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67720
Bug ID: 67720 Summary: [concepts] bug with recursive constrained function Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ryan.burn at gmail dot com Target Milestone: --- The below code is valid but gives this error with gcc: main.cpp: In instantiation of ‘auto f(const std::tuple<_El0, _El ...>&) requires predicate((cpt_BooleanFalseConstant<decltype(p((get<0>)(f::t)))>)()) [with TFirst = std::integral_constant<int, 9>; TRest = {std::integral_constant<int, 3>, std::integral_constant<int, 5>}]’: main.cpp:34:11: required from ‘auto f(const std::tuple<_El0, _El ...>&) requires predicate((cpt_BooleanFalseConstant<decltype(p((get<0>)(f::t)))>)()) [with TFirst = std::integral_constant<int, 6>; TRest = {std::integral_constant<int, 9>, std::integral_constant<int, 3>, std::integral_constant<int, 5>}]’ main.cpp:44:6: required from here main.cpp:34:11: error: call of overloaded ‘f(std::tuple<std::integral_constant<int, 3>, std::integral_constant<int, 5> >)’ is ambiguous return f(std::tuple<TRest...>()); ^ main.cpp:24:6: note: candidate: auto f(const std::tuple<_El0, _El ...>&) requires predicate((cpt_BooleanTrueConstant<decltype(p((get<0>)(f::t)))>)()) [with TFirst = std::integral_constant<int, 3>; TRest = {std::integral_constant<int, 5>}] auto f(const std::tuple<TFirst, TRest...>& t) ^ main.cpp:31:6: note: candidate: auto f(const std::tuple<_El0, _El ...>&) requires predicate((cpt_BooleanFalseConstant<decltype(p((get<0>)(f::t)))>)()) [with TFirst = std::integral_constant<int, 3>; TRest = {std::integral_constant<int, 5>}] auto f(const std::tuple<TFirst, TRest...>& t) //////////////////////////////////////////////////////////// #include <type_traits> #include <tuple> template <class X> requires requires { X::value; } constexpr bool lift_boolean_constant_value = X::value; template <class X> concept bool cpt_BooleanTrueConstant() { return requires { requires lift_boolean_constant_value<X>; }; } template <class X> concept bool cpt_BooleanFalseConstant() { return requires { requires !lift_boolean_constant_value<X>; }; } template<int X> auto p(std::integral_constant<int, X>) { return std::integral_constant<bool, (X < 5)>(); } template<class TFirst, class... TRest> auto f(const std::tuple<TFirst, TRest...>& t) requires cpt_BooleanTrueConstant<decltype(p(std::get<0>(t)))>() { return 1; } template<class TFirst, class... TRest> auto f(const std::tuple<TFirst, TRest...>& t) requires cpt_BooleanFalseConstant<decltype(p(std::get<0>(t)))>() { return f(std::tuple<TRest...>()); } int main() { std::tuple< std::integral_constant<int, 6>, std::integral_constant<int, 9>, std::integral_constant<int, 3>, std::integral_constant<int, 5> > t; f(t); return 0; } ////////////////////////////////////////////////////////////