Why doesn't overload resolution pick the first function?

c++, c++11

Solution

For an iterator type `foo`, `decltype(*foo)` is going to be `foo::value_type&`. A reference type is definitely not integral. You need to remove the reference (and possibly cv-qualification as well, IIRC) before evaluating the type with the `std::is_integral` trait, which is easily done with the `std::decay` transformation type trait:

template<bool B, typename V = void>
using enable_if = typename std::enable_if<B, V>::type;

template<typename T>
using decay = typename std::decay<T>::type;

template<typename ForwardIt>
auto f(ForwardIt first, ForwardIt)
    -> enable_if<std::is_integral<decay<decltype(*first)>>{}>
{
    std::cout << "Integral container type" << std::endl;
}

This will result in ambiguity with your other overload since both will now match. You will need to constrain the second overload as you suggest in the OP.

Problem

In the following program, both function calls print "Non-integral overload" even though I have an `enable_if` statement that restricts the function to integral container types only. Why is that? ``` #include <iostream> #include <vector> #include <type_traits> template<bool B, typename V = void> using enable_if = typename std::enable_if<B, V>::type; template<typename ForwardIt> auto f(ForwardIt first, ForwardIt) -> enable_if<std::is_integral<decltype(*first)>{}> { std::cout << "Integral container type" << std::endl; } template<typename ForwardIt> void f(ForwardIt, ForwardIt) { std::cout << "Non-integral container type" << std::endl; } int main() { struct X { }; std::vector<int> iv; std::vector<X> xv; f(iv.begin(), iv.end()); // "Non-integral container type" f(xv.begin(), xv.end()); // "Non-integral container type" } ``` I've even tried using `enable_if<!std::is_integral<...>>` on the second overload but to no avail.

Original source