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
}