The existing answers test for very specific properties of std::map, either that it is precisely a specialization of std::map (which would be false for std::unordered_map or non-standard types with the same interface as std::map), or testing that its value_type is exactly std::pair<const key_type, mapped_type> (which would be true for multimap and unordered_map, but false for non-standard types with similar interfaces).
This only tests that it provides key_type and mapped_type members, and can be accessed with operator[], so doesn't say that std::multimap is mappish:
#include <type_traits>
namespace detail {
  // Needed for some older versions of GCC
  template<typename...>
    struct voider { using type = void; };
  // std::void_t will be part of C++17, but until then define it ourselves:
  template<typename... T>
    using void_t = typename voider<T...>::type;
  template<typename T, typename U = void>
    struct is_mappish_impl : std::false_type { };
  template<typename T>
    struct is_mappish_impl<T, void_t<typename T::key_type,
                                     typename T::mapped_type,
                                     decltype(std::declval<T&>()[std::declval<const typename T::key_type&>()])>>
    : std::true_type { };
}
template<typename T>
struct is_mappish : detail::is_mappish_impl<T>::type { };
Because is_mappish has a "base characteristic" of either true_type or false_type you can dispatch on it like so:
template <typename T>
auto foo(const T& items, true_type)
{
    // here be maps
}
template <typename T>
auto foo(const T& items, false_type)
{
    // map-free zone
}
template <typename T>
auto foo(const T& items)
{ 
    return foo(items, is_mappish<T>{});
}
Or you can avoid dispatching entirely, and just overload foo for maps and non-maps:
template <typename T,
          std::enable_if_t<is_mappish<T>{}, int> = 0>
auto foo(const T& items)
{
    // here be maps
}
template <typename T,
          std::enable_if_t<!is_mappish<T>{}, int> = 0>
auto foo(const T& items)
{
    // map-free zone
}