I\'m wondering why in many template algorithms in the STL the arguments are not passed by reference but rather by value. Here is an example from the
Most algorithms modify their arguments. For instance, distance
might be implemented as follows1:
template
typename iterator_traits::difference_type
distance (InputIterator first, InputIterator last) {
typename iterator_traits::difference_type result{};
while (first++ != last)
++result;
return result;
}
Clearly this doesn’t work if you pass first
as a const
reference.
And it also doesn’t work if you pass it as a non-const
reference because in most calling contexts the caller’s objects cannot be modified (for instance if you pass the result of container.begin()
to the function.
Of course you could still pass by const
reference, make a copy inside the function and then modify that. At which point we’d have gained exactly nothing.
Coupled with the C++ standard recommendation that iterators should be lightweight types that should be cheap to copy, it’s more simple and in most cases more efficient to pass them by value:
But even still: cheap copying would be more expensive than no copying at all.
Not true. You also need to copy the reference (which, in the case of a non-inlined function call, is going to be implemented as a pointer). And then you need to dereference that pointer which also adds overhead. Compared to a straight copy which may be as cheap as copying a pointer in many cases, and doesn’t incur any dereferencing overhead.
1 Of course a real implementation would be optimised for random access iterators to have constant rather than linear runtime. The above implementation is for exposition only.