标签: string-view

std :: string_view究竟比const std :: string&更快?

std::string_view已经使它成为C++ 17,并且它被广泛推荐使用它代替const std::string&.

其中一个原因是表现.

有人可以解释与用作参数类型相比,究竟 std::string_view是什么/将会更快const std::string&?(假设在被叫方中没有副本)

c++ string string-view c++17

195
推荐指数
5
解决办法
3万
查看次数

什么是string_view?

string_view是C++ Library Fundamentals TS(N3921)中添加到C++ 17中的一个提议特性

据我所知,它是一种代表某种字符串"概念"的类型,它是任何类型的容器的视图,可以存储可视为字符串的东西.

  • 这是正确的吗 ?
  • 规范const std::string&参数类型应该 变成string_view吗?
  • 还有另一个重要的问题string_view需要考虑吗?

c++ fundamentals-ts string-view c++17

142
推荐指数
2
解决办法
5万
查看次数

为什么不支持连接std :: string和std :: string_view?

从C++ 1z开始,我们可以std::string_view轻松地查看连续的字符序列,避免不必要的数据复制.const std::string&现在经常建议使用,而不是使用参数std::string_view.

但是,很快就会发现切换const std::string&std::string_view使用字符串连接的中断代码,因为不支持连接std::stringstd::string_view:

std::string{"abc"} + std::string_view{"def"}; // ill-formed (fails to compile)
std::string_view{"abc"} + std::string{"def"}; // ill-formed (fails to compile)
Run Code Online (Sandbox Code Playgroud)

为什么不支持连接std::stringstd::string_view标准?

c++ string string-view c++17

47
推荐指数
2
解决办法
4035
查看次数

使用string_view进行地图查找

以下代码无法在最近的编译器上构建(g ++ - 5.3,clang ++ - 3.7).

#include <map>
#include <functional>
#include <experimental/string_view>

void f()
{
    using namespace std;
    using namespace std::experimental;
    map<string, int> m;
    string s = "foo";
    string_view sv(s);
    m.find(sv);
}
Run Code Online (Sandbox Code Playgroud)

clang返回的错误:

error: no matching member function for call to 'find'
    m.find(sv);
    ~~^~~~
Run Code Online (Sandbox Code Playgroud)

但是不find应该能够使用类似的类型?Cppreference提到了以下重载:

template< class K > iterator find( const K& x );

发生同样的错误boost::string_ref.

c++ dictionary c++14 string-view

26
推荐指数
1
解决办法
4847
查看次数

如何将std :: string_view转换为const char*?

使用带有标志的gcc-7.1进行编译时-std=c++17,以下程序会引发错误:

#include <string_view>
void foo(const char* cstr) {}
void bar(std::string_view str){
    foo(str);
}
Run Code Online (Sandbox Code Playgroud)

错误消息是

In function 'void bar(std::string_view)':
error: cannot convert 'std::string_view {aka std::basic_string_view<char>}' to 'const char*' for argument '1' to 'void foo(const char*)'
 foo(str);
Run Code Online (Sandbox Code Playgroud)

我很惊讶没有转换,const char*因为其他库(abseil,bde)提供了string_view隐式转换为的类似类const char*.

c++ string string-view c++17

22
推荐指数
3
解决办法
1万
查看次数

我何时会传递const&std :: string而不是std :: string_view?

我理解使用std :: string_view的动机;
它可以帮助避免函数参数中的不必要的分配.

例如:
以下程序将从std::string字符串文字创建一个.
这会导致不希望的动态分配,因为我们只对观察字符感兴趣.

#include <iostream>

void* operator new(std::size_t n)
{
    std::cout << "[allocating " << n << " bytes]\n";
    return malloc(n);
}

void observe_string(std::string const& str){}

int main(){
  observe_string("hello world"); //prints [allocating 36 bytes]
}
Run Code Online (Sandbox Code Playgroud)

使用string_view将解决问题:

#include <iostream>
#include <experimental/string_view>

void* operator new(std::size_t n)
{
    std::cout << "[allocating " << n << " bytes]\n";
    return malloc(n);
}

void observe_string(std::experimental::string_view const& str){
}

int main(){
  observe_string("hello world"); //prints nothing
}
Run Code Online (Sandbox Code Playgroud)

这给我留下了一个问题. …

c++ string stl parameter-passing string-view

19
推荐指数
3
解决办法
1966
查看次数

如何将std :: string_view转换为double?

我正在为应用程序的自定义选项文件编写c ++解析器.我有一个循环,option=value从文本文件的形式读取行value必须转换为double.在伪代码中,它执行以下操作:

while(not EOF)
    statement <- read_from_file
    useful_statement <- remove whitespaces, comments, etc from statement
    equal_position <- find '=' in useful_statement
    option_str <- useful_statement[0:equal_position)
    value_str <- useful_statement[equal_position:end)
    find_option(option_str) <- double(value_str)
Run Code Online (Sandbox Code Playgroud)

为了处理字符串拆分和传递给函数,我使用std::string_view它是因为它避免了过多的复制并清楚地说明了查看预先存在的段的意图std::string.我已经做了所有事情,指向其中std::string_view value_str确切部分的点useful_statement包含我想要提取的值,但我无法弄清楚从a中读取a double的方法std::string_view.

我知道std::stod哪个不起作用std::string_view.它允许我写

double value = std::stod(std::string(value_str));
Run Code Online (Sandbox Code Playgroud)

然而,这很难看,因为它转换为实际上不需要的字符串,即使它可能在我的情况下没有明显的差异,如果必须从文本中读取大量的数字,它可能会太慢文件.

另一方面,atof因为我无法保证null终止符,所以不起作用.我可以通过在构造它时添加\0来破解它useful_statement,但这会使代码混淆给读者并且如果代码被更改/重构则使其容易破解.

那么,什么是干净,直观和合理有效的方法呢?

c++ string-view c++17

19
推荐指数
1
解决办法
4078
查看次数

为什么std :: string_view在三元表达式中创建悬空视图?

考虑std::string_view从返回a 的方法const std::string&或从空字符串返回的方法。令我惊讶的是,以这种方式编写方法会导致悬空的字符串视图:

const std::string& otherMethod();

std::string_view myMethod(bool bla) {
    return bla ? otherMethod() : ""; // Dangling view!
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/1Hu_p2

似乎编译器首先将std::string结果的临时副本otherMethod()放在堆栈上,然后返回此临时副本的视图,而不是仅返回引用的视图。首先,我想到了一个comipler错误,但是G ++和clang都这样做。

修复很容易:将其包装otherMethod为一个显式结构即可string_view解决此问题:

std::string_view myMethod(bool bla) {
    return bla ? std::string_view(otherMethod()) : ""; // Works as intended!
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/Q-sEkr

为什么会这样呢?为什么原始代码会在没有警告的情况下创建隐式副本?

c++ language-lawyer dangling-pointer string-view c++17

19
推荐指数
1
解决办法
639
查看次数

安全地将 std::string_view 转换为 int(如 stoi 或 atoi)

是否有一种安全的标准方法可以转换std::string_viewint


由于 C++11std::string允许我们使用stoi转换为int

  std::string str = "12345";
  int i1 = stoi(str);              // Works, have i1 = 12345
  int i2 = stoi(str.substr(1,2));  // Works, have i2 = 23

  try {
    int i3 = stoi(std::string("abc"));
  } 
  catch(const std::exception& e) {
    std::cout << e.what() << std::endl;  // Correctly throws 'invalid stoi argument'
  }
Run Code Online (Sandbox Code Playgroud)

stoi不支持std::string_view。因此,或者,我们可以使用atoi,但必须非常小心,例如:

  std::string_view sv = "12345";
  int i1 = atoi(sv.data());              // Works, have …
Run Code Online (Sandbox Code Playgroud)

c++ string atoi string-view c++17

19
推荐指数
3
解决办法
8528
查看次数

为什么 std::string 没有直接接受 std::string_view 的构造函数?

为了允许std::stringstd::string_view模板构造函数进行构造

template<class T>
explicit basic_string(const T& t, const Allocator& alloc = Allocator());
Run Code Online (Sandbox Code Playgroud)

const T&仅当可转换为std::basic_string_view<CharT, Traits>链接)时才启用。

同时有专门的推演指南可以推演basic_stringbasic_string_view链接。该指南的评论说:

需要指南 (2-3),因为 std::basic_string_views 的 std::basic_string 构造函数被制作为模板,以避免在现有代码中引起歧义,并且这些模板不支持类模板参数推导。

所以我很好奇,需要有演绎指南和模板构造函数而不是简单的构造函数的歧义是什么std::basic_string_view,例如类似的东西

explicit basic_string(basic_string_view<CharT, Traits> sv, const Allocator& alloc = Allocator());
Run Code Online (Sandbox Code Playgroud)

请注意,我并不是问为什么构造函数被标记为显式。

c++ string constructor-overloading string-view c++17

19
推荐指数
1
解决办法
1028
查看次数