In your particular case, there is nothing to fuss and the garden: calculating the symbol number in a string (meaning std::string ) you can do it simply as symbol - line->begin() .
However, in general, a more abstract case, if you implement an algorithm that, by its nature, does not require random access to the data structure being used, but costs only sequential access, then a more reasonable solution would probably be If you use the counter. Thus, you still maintain the consistent structure of your algorithm, i.e. Solve the problem within a less demanding contract of sequential access.
Using iterator subtraction, you artificially introduce into the purely sequential algorithm a significantly stronger requirement for supporting random access . Do not unnecessarily impose too stringent requirements on data structures. If the task can be solved effectively within the framework of the idea of ββsequential access, then it is better to solve it within the framework of the idea of ββsequential access.
For example, if in a purely sequential algorithm you need to replace the vector with a list tomorrow, you will not have to make any alterations in the implementation of your algorithm. But it is enough to add iterator subtraction to such an algorithm - and everything becomes much more complicated.
Be careful with functions like std::distance . This function is intended primarily for the forced concealment of inefficiencies, i.e. in order to silently calculate the distance between iterators even when the iterators do not support effective distance calculation. That is, std::distance is almost always a crutch for very highly specialized situations from the category "here it is impossible to do without distance, even if its calculation is inefficient." Such situations should be carefully avoided.
symbol- line->begin()tried? - pavel