When you see that there is a small finite number of std::multi* containers, you can simply list them:
#include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <type_traits> template <typename Container> struct is_multi_container : std::false_type {}; template <typename T, typename Compare, typename Alloc> struct is_multi_container<std::multiset<T, Compare, Alloc>> : std::true_type {}; template <typename T, typename Compare, typename Alloc> struct is_multi_container<std::multimap<T, Compare, Alloc>> : std::true_type {}; template <typename T, typename Compare, typename Alloc> struct is_multi_container<std::unordered_multiset<T, Compare, Alloc>> : std::true_type {}; template <typename T, typename Compare, typename Alloc> struct is_multi_container<std::unordered_multimap<T, Compare, Alloc>> : std::true_type {};
There are more lines of code, but it is easy to read directly in his reasoning (i.e. it definitely works!).
Being an explicit list, the caveat is that it is not automatically distributed. For this, your decision is good. C ++ 14 may have an AssociativeContainer concept that will make this even easier; studies on this issue are left as an exercise for the reader .;)
Example:
#include <iostream> #include <iomanip> int main() { std::cout << std::boolalpha; #define TEST(type, ...) \ std::cout << type " is: " \ << is_multi_container<__VA_ARGS__>::value \ << std::endl TEST("std::set<T>", std::set<int>); TEST("std::multiset<T>", std::multiset<int>); TEST("std::map<K,T>", std::map<int, double>); TEST("std::multimap<K,T>", std::multimap<int, double>); TEST("std::unordered_set<T>", std::unordered_set<int>); TEST("std::unordered_multiset<T>", std::unordered_multiset<int>); TEST("std::unordered_map<K,T>", std::unordered_map<int, double>); TEST("std::unordered_multimap<K,T>", std::unordered_multimap<int, double>); }
Output:
std::set<T> is: false std::multiset<T> is: true std::map<K,T> is: false std::multimap<K,T> is: true std::unordered_set<T> is: false std::unordered_multiset<T> is: true std::unordered_map<K,T> is: false std::unordered_multimap<K,T> is: true