Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to make a function accept all type of iterators, but specialising only one type?

As per How to make constructor accept all type of iterators? I am trying to have a function accept iterators from different container types. Unlike that question, i want those containers to have only the specific type of elements. However, if i use the following code, i lose the ability to control the element type:

template<std::input_iterator ITER>
void f(ITER start, ITER end)
{
    for(auto it=start; it!=end; ++it)
    {
        static_assert(std::is_arithmetic<decltype(*it)>::value, "Not arithmetic");
    }
}

In here static_assert is not a very poor solution, because the error that i get is anything, but trivial to understand.

Let’s imagine my main as

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

int main()
{
    std::vector<int> v_good{{1, 2, 3, 4, 5}};
    std::vector<std::string> v_bad{{std::string("hello"), std::string("world")}};
    std::list<int> l_good{{1, 2, 3, 4, 5}};
    
    f(v_good.begin(), v_good.end());
    f(l_good.begin(), l_good.end());
    f(v_bad.begin(), v_bad.end()); // at this point i want to get a compilation error
    
    return 0;
}

>Solution :

You can constrain the value_type of the iterator (std::iter_value_t) to be an arithmetic type by

template<std::input_iterator ITER>
  requires std::is_arithmetic_v<std::iter_value_t<ITER>>
void f(ITER start, ITER end)
{
    for (auto it=start; it!=end; ++it)
    {
       // ...
    }
}

In C++20, the type returned by a range’s end() (i.e., the sentinel type) can be different from its begin(), so you may also need

template<std::input_iterator ITER, std::sentinel_for<ITER> SENT>
  requires std::is_arithmetic_v<std::iter_value_t<ITER>>
void f(ITER start, SENT end)
{
    for(auto it=start; it!=end; ++it)
    {
       // ... 
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading