I know that the question was asked 5 years ago, but this is what I did without any requirements beyond c++11
:
/// @brief container traits
////////////////////////////////////////////////////////////////////////////////
namespace container_traits {
using tc = char[2];
template<typename T> struct is_container {
static tc& test(...);
template <typename U>
static char test(U&&, decltype(std::begin(std::declval<U>()))* = 0);
static constexpr bool value = sizeof(test(std::declval<T>())) == 1;
};
template < typename T > struct is_associative {
static tc& test(...) ;
template < typename U >
static char test(U&&, typename U::key_type* = 0) ;
static constexpr bool value = sizeof( test( std::declval<T>() ) ) == 1 ;
};
}
template < typename T > struct is_container :
std::conditional<(container_traits::is_container<T>::value || std::is_array<T>::value)
&& !std::is_same<T, std::string>::value
&& !std::is_same<T, const std::string>::value, std::true_type, std::false_type >::type {};
template < typename T > struct is_associative :
std::conditional< container_traits::is_container<T>::value && container_traits::is_associative<T>::value, std::true_type, std::false_type >::type {};
////////////////////////////////////////////////////////////////////////////////
/// @brief no std::enable_if_t in c++11
////////////////////////////////////////////////////////////////////////////////
#if __cplusplus <= 201103L
namespace std {
template< bool B, class T = void >
using enable_if_t = typename std::enable_if<B,T>::type;
}
#endif