Home > Software design >  constraint a template to be iterable using concepts in C 20
constraint a template to be iterable using concepts in C 20

Time:11-02

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, int len){
  // some code here
}

Now I want to make sure I constraint 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 iterables, but I am not sure how this applies to my case.

CodePudding user response:

An important distinction between "old-school" iterators and their modern interpretation is that the sentinel (aka end iterator) does not necessarily have to be the same type as the begin one.

So you should be using 2 separate concepts. One for the iterator itself, and another one for the sentinel, using std::sentinel_for:

As for the iterator itself, you will want to use the stricter concept that matches how you will consume it. Ideally std::input_iterator if possible.

Applying the constraint is simply a matter of replacing typename in the template by the appropriate concept:

#include <iterator>

template<std::input_iterator I, std::sentinel_for<I> S>
auto find_median_sorted(I begin, S end){
  // some code here
}

CodePudding user response:

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 conatiner, int len) {
    // some code here
}

To restrict the ranges to be only for random access iterators, you can use the std::random_access_iterator as follows:

#include <iterator> // std::random_access_iterator 

template<typename  T>
decltype(auto) find_median_sorted(T conatiner, int len)
requires std::random_access_iterator<decltype(conatiner.begin())>
{
    // some code here
}
  •  Tags:  
  • c
  • Related