Is it possible to write a type trait whose value is true for all common STL structures (e.g., vector, set, map, ...)?
To get started, I'd like to write a type trait that is true for a vector and false otherwise. I tried this, but it doesn't compile:
template<class T, typename Enable = void> struct is_vector {   static bool const value = false; };  template<class T, class U> struct is_vector<T, typename boost::enable_if<boost::is_same<T, std::vector<U> > >::type> {   static bool const value = true; };   The error message is template parameters not used in partial specialization: U. 
What is a type trait? A type trait is a simple template struct that contains a member constant, which in turn holds the answer to the question the type trait asks or the transformation it performs.
The type-traits library also contains a set of classes that perform a specific transformation on a type; for example, they can remove a top-level const or volatile qualifier from a type. Each class that performs a transformation defines a single typedef-member type that is the result of the transformation.
Look, another SFINAE-based solution for detecting STL-like containers:
template<typename T, typename _ = void> struct is_container : std::false_type {};  template<typename... Ts> struct is_container_helper {};  template<typename T> struct is_container<         T,         std::conditional_t<             false,             is_container_helper<                 typename T::value_type,                 typename T::size_type,                 typename T::allocator_type,                 typename T::iterator,                 typename T::const_iterator,                 decltype(std::declval<T>().size()),                 decltype(std::declval<T>().begin()),                 decltype(std::declval<T>().end()),                 decltype(std::declval<T>().cbegin()),                 decltype(std::declval<T>().cend())                 >,             void             >         > : public std::true_type {};  Of course, you might change methods and types to be checked.
If you want to detect only STL containers (it means std::vector, std::list, etc) you should do something like this.
UPDATE. As @Deduplicator noted, container might not meet  AllocatorAwareContainer requirements (e.g.: std::array<T, N>). That is why check on T::allocator_type is not neccessary. But you may check any/all Container requirements in a similar way.
Actually, after some trial and error I found it's quite simple:
template<class T> struct is_vector<std::vector<T> > {   static bool const value = true; };   I'd still like to know how to write a more general is_container. Do I have to list all types by hand?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With