查找 string_view 开头与其基础字符串之间距离的最佳方法

Best way to find distance between beginning of string_view and its underlying string

给定 std::string sstd::string_view s_view。找到 s_view 开头和 s 之间距离的“最佳”方法是什么?我所说的“最佳”是指什么对所有主要的 C++ 编译器都安全?

下面的代码示例说明了我能想到的两个选项。我不确定这两种方法是否总是适用于所有主要编译器。此外,我不禁觉得有一种更“正确”的方法可以做到这一点,但我找不到任何 std::stringstd::string_view 方法可以实现这一点。

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;
}

使用 clang++ main.cpp -std=c++11 在 mac 上使用 Apple clang 版本 11.0.0 编译。它打印:

Pointer difference: 3
Iterator distance: 3

std::string_view 对正在查看的 std::string 没有概念。它所知道的只是给定的起始 char* 数据指针。

比较来自不同容器的迭代器是未定义的行为,即使它们引用相同的基础数据也是如此。

因此,您唯一的选择是比较原始指针,就像您在 "Pointer difference" 示例中所做的那样。如果你想比较迭代器,你必须先将它们解引用为指针,例如:

std::cout << "Pointer distance via Iterators: "
            << (&*s_view.begin() - &*s.begin())
            << std::endl;

Live Demo