Thanks – namespace pollution was the source of my confusion I think also!
#include <iostream> #include <vector> #include <list> #include <forward_list> #include <concepts> namespace john { template<typename I, typename T> requires std::forward_iterator<I> && std::integral<T> void advance(I &iter, T n) { std::cout << "forward iterator" << "\n"; } template<std::bidirectional_iterator I, std::integral T> void advance(I &iter, T n) { std::cout << "bidirectional iterator" << "\n"; } template<std::random_access_iterator I, std::integral T> void advance(I &iter, T n) { std::cout << "random_access iterator" << "\n"; } } int main() { std::cout << "\n"; std::forward_list fList{1, 2, 3}; auto itFor = fList.begin(); john::advance(itFor, 2.3f); std::list li{1, 2, 3}; auto liter = li.begin(); john::advance(liter, 2.5); std::vector vec{1, 2, 3}; auto vIter = vec.begin(); john::advance(vIter, 2); std::cout << "\n"; }