#include <vector>
#include <iostream>

/////////////////////////////////////////////////////////////////////////////
// Data struct
/////////////////////////////////////////////////////////////////////////////

struct point { 
    point(int x, int y):x(x), y(y) {} 
    int x, y ;
} ;

/////////////////////////////////////////////////////////////////////////////
// Specialized access function template
/////////////////////////////////////////////////////////////////////////////

namespace tag{
    struct x{};
    struct y{};
}

template <typename T> int& access(point& p) ;
template <> int& access<tag::x>(point& p) { return p.x ; }
template <> int& access<tag::y>(point& p) { return p.y ; }

template <typename T>
int max ( std::vector<point>& v) {
        int result = access<T>(v[0]) ;
        for ( std::vector<point>::size_type i = 1; i != v.size(); ++i )
                if(access<T>(v[i]) > result)
                        result = access<T>(v[i]) ;
        return result ;
}

/////////////////////////////////////////////////////////////////////////////
// main
/////////////////////////////////////////////////////////////////////////////

int main()
{
    std::vector<point> v ;
    v.push_back(point(1, 9));
    v.push_back(point(2, 8));
    v.push_back(point(3, 7));
    v.push_back(point(4, 6));
    v.push_back(point(5, 5));

    // Specialized access function template
    std::cout << max<tag::x>(v) << std::endl ;
    std::cout << max<tag::y>(v) << std::endl ;
}