https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67018
Bug ID: 67018 Summary: [c++-concepts] Failure to partially order function templates by constraints Product: gcc Version: c++-concepts Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 36058 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36058&action=edit Preprocessed test case Compiling this program - preprocessed test case attached - with r226205: #include <stl2/iterator.hpp> template<stl2::InputIterator> constexpr bool f() { return false; } // Line 4 template<stl2::ForwardIterator> constexpr bool f() { return true; } // Line 6 int main() { static_assert(f<int*>()); // Line 9 } results in the error: ~/concept-gcc/bin/g++ -std=gnu++1z -I ~/cmcstl2/include -I ~/cmcstl2/meta/include simplefoo.cpp -c simplefoo.cpp: In function ‘int main()’: simplefoo.cpp:9:25: error: call of overloaded ‘f()’ is ambiguous static_assert(f<int*>()); ^ simplefoo.cpp:4:16: note: candidate: constexpr bool f() [with <template-parameter-1-1> = int*] constexpr bool f() { return false; } ^ simplefoo.cpp:6:16: note: candidate: constexpr bool f() [with <template-parameter-1-1> = int*] constexpr bool f() { return true; } Given that the ForwardIterator concept directly refines InputIterator: template <class I> concept bool ForwardIterator() { return InputIterator<I>() && Incrementable<I>() && DerivedFrom<IteratorCategory<I>, forward_iterator_tag>(); } the constraints of the ForwardIterator overload of f subsume those of the InputIterator overload and the two templates should be ordered appropriately. In the definition of WeakInputIterator, which InputIterator refines: template <class I> concept bool WeakInputIterator() { return WeakIterator<I>() && Readable<I>() && requires (I& i, const I& ci) { typename IteratorCategory<I>; DerivedFrom<IteratorCategory<I>, weak_input_iterator_tag>(); requires Readable<decltype(i++)>(); requires Same<ValueType<I>, ValueType<decltype(i++)>>(); { *ci } -> const ValueType<I>&; }; } template <class I> concept bool InputIterator() { return WeakInputIterator<I>() && Iterator<I>() && DerivedFrom<IteratorCategory<I>, input_iterator_tag>(); } commenting out the line requires Readable<decltype(i++)>(); makes the test compile and behave as expected.