Iterators – generalizations of pointers – are expected to be copied cheaply. The copy cost is never raised as an issues.
Iterators are usually passed by value. Sutter and Alexandrescu recommended (P154 in their book) putting iterators into containers rather than putting pointers into containers. Containers would copy the iterators by value.
someContainer.end() often returns a temp object, so taking its address is a bug. The returned iterator object from end() must be passed by Value.
Someone online said that If an argument is taken by value, this makes it usually easier for the compiler to optimize the code. Look at the advantage of using function objects by value instead of taking function pointers. This is a similar reason for by-value parameters reasoned on the level of functions objects.
Note java/c# arguments are predominently passed by reference.