用 std::string_view 替换所有 const std::string & 是一个不错的选择吗?

问题描述 投票:0回答:1

我对内存分配和复制非常敏感,因此,如果函数需要

std::string
对象作为输入,我总是使用
const std::string &

最近,我发现如果我传入一个

const std::string &
std::string
将会构造一个
char[]
对象。请看这个:

#include <iostream>
#include <string>
         
using namespace std;
         
void test_string(const std::string & s) {  // use std::string_view here is better
  // it can avoid local variable allocation
  printf("%p\n", s.data());
}        
         
int main() {
  char aa[] = "asd";
  test_string(aa);
  printf("%p\n", aa);
}

我用

const std::string &
更改了
std::string_view
,它解决了不必要的构造或副本。所以,我认为
std::string_view
值得在任何地方使用。

我把所有的

const std::string &
都换成了
std::string_view
,如果有地方需要用
std::string
,我就用
.data()
来获取字符串。

问题发生在以下情况。

inline std::vector<std::string_view> Split(std::string_view str, std::string_view delim, const bool trim_empty = false) {
    if (str.empty()) return {}; 
    size_t pos, last_pos = 0, len;
    std::vector<std::string_view> tokens;
    while (true) {
      pos = str.find(delim, last_pos);
      if (pos == std::string::npos) pos = str.size();
      len = pos - last_pos;
      if (!trim_empty || len != 0) tokens.push_back(str.substr(last_pos, len));
      if (pos == str.size()) break; 
      else last_pos = pos + delim.size();
    }   
    return tokens;
  }

我用它来将

string
拆分为
vector
,如您所见,
std::stringview
避免了复制和大内存分配。

但是问题发生在使用 std::stringview 时。

std::string str = "asd\nbn\ncd\n\n";
std::unordered_map<std::string, int> m;
m["asd"] = 2;
const auto & v = Split(str, "\n");
const auto & it = m.find(v.front().data());

此操作失败,因为

v.front().data()
返回整个字符串,而不是第一部分。

我知道这是由于字符串流中没有

"\0"
造成的。

除了构建一个

std::string_view
之外,似乎没有找到正确的
std::string(v.front().data())
的好方法。

那么,有什么办法可以让

.data()
如期而至呢?或者用 std::stringview 替换 const std::string & 只是不是一个总是好的选择?

c++ string stl c++17
1个回答
0
投票

std::string_view::data()
返回一个不一定以 null 终止的指针。
std::string::data()
返回一个always以null结尾的指针。

既然你无论如何都要构造临时

std::string
,请正确执行:
std::string{v.front()}
将构造正确长度的字符串。

或者,如果这是

Split
的唯一用途,则根本不要使用
std::string_view
,如果仅使用
string_view
来构造
string
似乎不会有太多收获.

© www.soinside.com 2019 - 2024. All rights reserved.