C++:异质查找(heterogeneous lookup)
太久没更新博文了,水一篇凑数 从 String View 说起 C 风格的字符串常常需要自己记录长度、管理生命周期,涉及长度变化时更是比较麻烦。于是在 C++ 中我们有了 std::string,并且有了与之配套的一系列函数,比如 std::stoi,对应 C 里面的 atoi。这个函数的声明如下: int stoi(const std::string& str, std::size_t* pos = 0, int base = 10); 这个接口接受一个 const std::string&,乍看或许是理所应当的:我是 C++ 函数,我需要读取字符串,但是我不需要修改它。实际上,C++ 中有很多接受 const std::string& 的函数,然而很遗憾,这个设计是失败的。 考虑这样一种情况,我们需要读取一个 std::string 里的子串,但我们不需要修改它。比如对一个拥有很多数字的字符串进行连续 parse ,或者在某个大文本里找到某个模板再对匹配结果进行进一步筛选。这种情况下,这些接受 const std::string& 的函数就变得不好用了,因为子串不是一个 std::string 对象。我们往往不得不把子串复制到一个新的 std::string 对象里,造成了额外的开销。 类似的常见情况还有,我们接收到了一个 C 风格的字符串,以 char* str + size_t len 的形式,而我们希望能在这个字符串上使用各种 C++ 函数的功能。比如跟 C 接口交互的时候,或者用 buffer 从别的地方接收字符串数据的时候。 所以要怎么解决呢?我们可以采用 C 风格的接口,即 char* str + size_t len,或者采用迭代器风格的接口,即 char* begin + char* end。而将这两个参数合起来,我们就得到了 std::string_view ——只读字符串接口的正确答案。它不仅比 const std::string& 更泛用,而且在没有发生 SSO 的情况下,它还比 const std::string& 减少了一次指针跳转。...