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 c 17, 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 c 17, it's pretty trivial to implement your own version of std::as_const
. Just make sure you declare it outside of namespace std
.