Search code examples
c++templatesc++11stlstatic-assert

Elegant way to static_assert() that a standard library container type is ordered?


In a templated function where one parameter is a standard library container of type T, can I easily statically assert that T is an ordered container?

Is there a more elegant way to do this than to do something type-specific, like test for the presence of a hash_function() function to distinguish between std::map and std::unordered_map ?


Solution

  • Another simple one:

    template <template <typename...> class Container>
    struct is_ordered : std::false_type {};
    
    template <> struct is_ordered<std::map>      : std::true_type {};
    template <> struct is_ordered<std::set>      : std::true_type {};
    template <> struct is_ordered<std::multimap> : std::true_type {};
    template <> struct is_ordered<std::multiset> : std::true_type {};
    

    and then just static_assert(is_ordered<Container>::value, "error") to use it. It's pretty easy to extend to custom containers too: just add a line like the above.

    If you don't want to use template-templates at the call site, you can always wrap it ala:

    template <typename T> struct is_ordered_2 : std::false_type {};
    template <template <typename...> class Container, typename... Ts>
    struct is_ordered_2<Container<Ts...>> : is_ordered<Container> {};
    

    and then you can use it either way.