Given an std::string s
and std::string_view s_view
. What is the "best" way to find the distance between the beginning of s_view
and s
? By "best" I mean what works safely for all of the main C++ compilers?
The two options I can think of are illustrated by the code example below. I am unsure if these two ways of doing it will always work on all main compilers. Also, I can't help but feeling that there is a more "proper" way of doing it, but I couldn't find any std::string
or std::string_view
methods that would achieve this.
main.cpp
#include <iostream>
#include <string>
int main() {
std::string s{"0123456789"};
std::string_view s_view{s.data() + 3, 4};
std::cout << "Pointer difference: "
<< (s_view.data() - s.data()) << std::endl;
std::cout << "Iterator distance: "
<< std::distance(std::string_view{s}.begin(), s_view.begin())
<< std::endl;
return 0;
}
Compiled on a mac with Apple clang version 11.0.0 using clang++ main.cpp -std=c++11
. It prints:
Pointer difference: 3
Iterator distance: 3
std::string_view
has no concept of the std::string
it is viewing. All it knows is the starting char*
data pointer it was given.
It is undefined behavior to compare iterators from different containers, even if they refer to the same underlying data.
So, your only option is to compare raw pointers, like you do in your "Pointer difference"
example. If you want to compare iterators, you will have to dereference them into pointers first, eg:
std::cout << "Pointer distance via Iterators: "
<< (&*s_view.begin() - &*s.begin())
<< std::endl;