#include <iostream>

template < typename T > void foo( T, typename T::const_iterator* = nullptr )
{ std::cout << "(1) this type defines a nested type 'const_iterator'\n" ; }

template < typename T > void foo( T, typename T::first_type* = nullptr )
{ std::cout << "(2) this type defines a nested type 'first_type'\n" ; }

template < typename T > void foo( T, typename T::result_type* = nullptr )
{ std::cout << "(3) this type defines a nested type 'result_type'\n" ; }

#include <vector>
#include <utility>
#include <functional>

int main()
{
    std::vector<int> a ;
    foo(a) ; // (1) this type defines a nested type 'const_iterator'
    // substitution failure for (2) and (3)

    std::pair<int,int> b ;
    foo(b) ; // (2) this type defines a nested type 'first_type'
    // substitution failure for (1) and (3)

    std::function< bool(int,int) > c ;
    foo(c) ; // (3) this type defines a nested type 'result_type'
    // substitution failure for (1) and (2)
}
