#include <iostream>
//First, some boilerplate to do easy argument dependent lookup of `begin` in a context where `std::begin` is visible:

    #include <utility>
    #include <iterator>
    namespace adl_details {
      using std::begin; using std::end;
      template<class R>
      decltype(begin(std::declval<R>())) adl_begin(R&&r){
        return begin(std::forward<R>(r));
      }
      template<class R>
      decltype(end(std::declval<R>())) adl_end(R&&r){
        return end(std::forward<R>(r));
      }
    }
    using adl_details::adl_begin;
    using adl_details::adl_end;
//This is required to reasonably emulate how range-based `for(:)` loops find their begin/end iterators.  By packaging it up like this, we reduce boilerplate below.

//Next, some C++1y style utility aliases:

    template<class>struct sink {using type=void;};
    template<class X>using sink_t=typename sink<X>::type;
    template<bool b, class T=void>using enable_if_t=typename std::enable_if<b,T>::type;
//`sink_t` takes any type, and throws it away replacing it with `void`.

//`enable_if_t` removes annoying `typename` spam below.

//In an industrial strength library, we'd put this in `detail`s, and have a 1-type-argument version that dispatches to it.  But I don't care:

    template<class I,class=void> struct is_iterator:std::false_type{};
    template<> struct is_iterator<void*,void>:std::false_type{};
    template<> struct is_iterator<void const*,void>:std::false_type{};
    template<> struct is_iterator<void volatile*,void>:std::false_type{};
    template<> struct is_iterator<void const volatile*,void>:std::false_type{};
    template<class I>struct is_iterator<I,
      sink_t< typename std::iterator_traits<I>::value_type >
    >:std::true_type{};
//`is_iterator` doesn't do heavy auditing of the `iterator_traits` of `I`.  But it is enough.

    template<class R>
    using begin_t=decltype(adl_begin(std::declval<R&>()));
    template<class R>
    using end_t=decltype(adl_end(std::declval<R&>()));
//These two type aliases make the stuff below less annoying.

//Again, in industrial strength libraries, put 2-arg-with-`void` into `details`:

    template<class R,class=void> struct has_iterator:std::false_type{};
    template<class R>
    struct has_iterator<
      R,
      enable_if_t<
        is_iterator<begin_t<R>>::value
        && is_iterator<end_t<R>>::value
        // && std::is_same<begin_t<R>,end_t<R>>::value
      >
    >:std::true_type{};
//Note the commented out line in the `enable_if_t` above.  I left that out to allow asymmetric iteration to work, where the `end` is a type that has a different `operator==` overload.  Such is being considered for C++17: it allows really, really efficient algorithms on null-terminated strings (for example).

//Finally, the final output:
    
    template<class R>using iterator_t=enable_if_t<has_iterator<R>::type, begin_t<R>>;
//which evaluates to the iterator of the iterable range `R` iff it has one.

//There are cases where this won't work, but they are pathological.

int main() {
	int X[3];
	std::cout << has_iterator<decltype(X)>::value << "\n";
	begin_t<decltype(X)> x;
	std::cout << is_iterator<int*>::value << is_iterator<begin_t<decltype(X)>>::value << "\n";
	std::cout << is_iterator<void*>::value << "\n";
	std::cout << is_iterator<int>::value << "\n";
	return 0;
}