我已经在一些旧代码中添加了std::string_view
s来表示字符串,比如配置参数,因为它提供了一个只读视图,由于不需要复制,所以速度更快。
但是,不能将两个string_view
连接在一起,因为没有定义operator+
。我看到this question有几个答案,说明这是一个疏忽,并有一个建议,在添加。但是,这是为了添加string
和string_view
,假设如果实现了这一点,则产生的串联将是std::string
添加两个string_view
是否也属于同一类别?如果不是,为什么不支持添加两个string_view
?
样品
std::string_view s1{"concate"};
std::string_view s2{"nate"};
std::string_view s3{s1 + s2};
字符串
这里有个错误
error: no match for 'operator+' (operand types are 'std::string_view' {aka 'std::basic_string_view<char>'} and 'std::string_view' {aka 'std::basic_string_view<char>'})
型
4条答案
按热度按时间5t7ly7z51#
视图类似于span,因为它不拥有数据,顾名思义,它只是数据的视图。要连接字符串视图,首先需要构造一个
std::string
,然后才能连接。字符串
请注意,
s3
将是std::string
而不是std::string_view
,因为它将拥有此数据。mwyxok5s2#
std::string_view
是std::basic_string_view<char>
的别名,std::basic_string_view<char>
是以特定类型的字符为模板的std::basic_string_view
,即char
的值。但它看起来像什么?
除了大量有用的成员函数,如
find
,substr
和其他(如果与STL提供的其他容器/字符串类似的东西相比,它可能是一个普通的数字),std::basic_string_view<_CharT>
,_CharT
是通用的char
类型,只有2个数据成员,字符串
即,指向X1 M10 N1 X的X1 M9 N1 XANT指针,以指示视图从哪里开始,以及X1 M11 N1 X(适当类型的数字),以指示视图从X1 M12 N1 X的指针开始多长时间。
换句话说,一个字符串视图只知道它从哪里开始,有多长,所以它表示一个类似
char
的实体序列,这些实体在内存中是连续的。只有两个这样的成员,您不能表示由不连续的子字符串组成的字符串。换句话说,如果你想创建一个
std::string_view
,你需要知道它有多少个char
,以及从哪个位置开始。你能告诉s1 + s2
应该从哪里开始,它应该有多少个字符长吗?想想看吧:你不能,因为s1
和s2
不相邻。也许一个图表可以帮助。
假设这几行代码
型
s1
和s2
是完全不相关的对象,就它们的内存位置而言;以下是它们的样子:型
我故意把它们画得不对齐,意思是
&s1[0]
,s1
开始的内存位置,和&s2[0]
,s2
开始的内存位置,彼此没有任何关系。现在,假设你创建了两个字符串视图,如下所示:
型
以下是它们的外观,根据两个实现定义的成员
_M_str
和_M_len
:型
考虑到上面的情况,你能看出期望这样做有什么错吗
型
工作?
如何定义
s3._M_str
和s3._M_len
(基于s1._M_str
、s1._M_len
、s2._M_str
和s2._M_len
),使它们表示"helloworld"
上的视图?不能,因为
"hello"
和"world"
位于两个不相关的内存区域。wi3ka0sx3#
std::string_view
不拥有任何数据,它只是一个视图。如果要连接两个视图以获得连接视图,可以使用Boost库中的boost::join()
。但结果类型将不是std::string_view
。字符串
C++23已联接了标准库中名为
std::ranges::views::join_with_view
的范围型
hgc7kmma4#
std::string_view
是一个轻量级的、不拥有角色的视图。要获得一个连接多个字符串视图的视图,我们可以使用C++20中引入的 join 视图适配器:
字符串
这给了我们一个视图对象,可以使用标准算法或基于范围的
for
来迭代。它可以转换为std::string
对象(但不能直接转换为std::string_view
,因为这需要我们将内容复制到某个地方以使它们连续)。完整演示:
型