https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80064
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org --- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- I think the testcase is invalid. std::make_heap is declared like so: template<class RandomAccessIterator> void make_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); The explicit instantiation matches the second overload, then argument substitition creates the function: void make_heap(vector<int>::iterator first, vector<int>::iterator last, bool(comp)(int, int)); You can't pass functions by value so the third argument decays to: void make_heap(vector<int>::iterator first, vector<int>::iterator last, bool(*comp)(int, int)); However, this means the type of the function parameter comp is no longer of type Compare, and so if the implementation tries to use that type it will fail, e.g. GCC 7 does something like: struct wrapper { Compare cmp; } wrapped_comp = { comp }; And libc++ does something like: Compare& ref = comp; Both fail, because Compare is a function type, but comp is a pointer to function. The test should use: std::make_heap<std::vector<int>::iterator, bool(*)(int, int)> That is the actual type that is deduced for the greater argument.