Search code examples
c++templatesaliastype-traits

Check if a container can be traversed backwards in C++


I'm writing a template which can take any container to store values into. I need to check if the container passed into the template wrapper can be traversed backwards (or, normatively speaking, meets the ReversibleContainer requirement). To provide a bit more context, here is a simple piece of code:

using container = ... // assume the container alias to represent the container
                      // passed in as a template parameter
...
using reverse_iterator = std::conditional_t<???, container::reverse_iterator, container::iterator>;

Is there any type trait for this or some other workaround? How can I implement this?


Solution

  • This is a fairly straightforward application of SFINAE, has_reverse_iterator<T> will evaluate to true if T defines a reverse_iterator member type.

    #include <type_traits>
    #include <vector>
    #include <forward_list>
    
    template<typename T, typename=void>
    struct has_reverse_iterator : std::false_type {};
    
    template<typename T>
    struct has_reverse_iterator<T,
                    typename std::void_t<typename T::reverse_iterator>>
        : std::true_type {};
    
    template<typename T>
    inline constexpr bool has_reverse_iterator_v=has_reverse_iterator<T>::value;
    
    static_assert(has_reverse_iterator_v<std::vector<char>>);
    
    static_assert(!has_reverse_iterator_v<std::forward_list<char>>);