Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 374
Chris Kline Avatar asked Feb 10 '14 16:02

Chris Kline


2 Answers

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.

like image 64
bstamour Avatar answered Oct 15 '22 11:10

bstamour


This approach is pretty simple:

// default result
template<class T>constexpr bool IsOrdered(const T&) {return false;}

// now enumerate the ordered standard library types of interest:
template<class K, class T, class C, class A>
constexpr bool IsOrdered(const std::map<K,T,C,A>&) {return true;}
// ...remaining types...
like image 44
justin Avatar answered Oct 15 '22 13:10

justin