Search code examples
c++templatesc++20c++-conceptsfunction-templates

How to constraint a template to be iterable ranges using concepts?


Say I have some template function that returns the median of some iterable object passed into it.

Something like:

template<typename T>
decltype(auto) find_median_sorted(T begin)
{
  // some code here
}

Now I want to make sure I constrained T to always be iterable. I am trying to learn how to use concepts in C++, so is there some way I can use concept here to make sure T is iterable?

I'm sure there are other ways to check if it is iterable, but is this a wrong use case for concepts? I also came across this post here related to element iterable, but I am not sure how this applies to my case.


Solution

  • I am trying to learn how to use concepts in C++, so is there some way I can use concept here to make sure T is iterable?

    You can have standard concept std::ranges::range from <ranges> header here. With that your function will look like:

    #include <ranges>  // std::ranges::range
    
    template<std::ranges::range T>
    decltype(auto) find_median_sorted(T const& container) {
        // some code here
    }
    

    To restrict the ranges to be only for random access iterable ranges, you can use either std::ranges::random_access_range again from <ranges> header

    #include <ranges>  // std::ranges::random_access_range
    
    template<std::ranges::random_access_range T>
    decltype(auto) find_median_sorted(T const& container) {
        // some code here
    }
    

    or via iterator concept std::random_access_iterator as follows:

    #include <iterator> // std::random_access_iterator 
    
    template<typename  T>
    decltype(auto) find_median_sorted(T const& container)
    requires std::random_access_iterator<std::ranges::iterator_t<T>>
    {
        // some code here
    }