Home > other >  Const correctness in generic functions using iterators
Const correctness in generic functions using iterators

Time:08-09

I want to write a generic functions that takes in a sequence, while guaranteeing to not alter said sequence.

template<typename ConstInputIter, typename OutputIter>
OutputIter f(ConstInputIter begin, ConstInputIter end, OutputIter out)
{
  InputIter iter = begin;
  do
  {
    *out   = some_operation(*iter);
  }while(iter!=end);
  return out;
}

Yet the above example still would take any type as ConstInputIterator, not just const ones. So far, the notion towards being const in it is nominal.

How do I declare the sequence given will not be altered by this function?

CodePudding user response:

Even in C 20, there is no generic way to coerce an iterator over a non-const T into an iterator over a T const. Particular iterators may have a mechanism to do that, and you can use std::cbegin/cend for ranges to get const iterators. But given only an iterator, you are at the mercy of what the user provides.

Applying a C 20 constraint (requiring iter_value_t to be const) is the wrong thing, as your function should be able to operate on a non-const range.

CodePudding user response:

Since , you can use std::as_const every time you deference your iterator:

// ...
*out   = some_operation(std::as_const(*iter));
// ...

This makes sure you never access the elements of the underlying container through a non-const l-value reference.

Note: if you don't have access to , it's pretty trivial to implement your own version of std::as_const. Just make sure you declare it outside of namespace std.

  • Related