此代码具有未定义的行为:
#include <string_view>
#include <iostream>
using namespace std::string_view_literals;
void foo(std::string_view msg) {
std::cout << msg.data() << '\n'; // undefined behavior if 'msg' is not null-
// terminated
// std::cout << msg << '\n'; is not undefined because operator<< uses
// iterators to print 'msg', but that's not the point
}
int main() {
foo("hello"sv); // not null-terminated - undefined behavior
foo("foo"); // same, even more dangerous
}
Run Code Online (Sandbox Code Playgroud)
原因是它std::string_view可以存储非空终止字符串,并且在调用时不包含空终止符data.这是非常有限的,为了使上面的代码定义行为,我必须构建一个std::string它:
std::string str{ msg };
std::cout << …Run Code Online (Sandbox Code Playgroud) 我需要std::string在所有空间拆分.但是,结果范围应该将其元素转换为std::string_views.我正在努力研究该系列的"元素类型".我想,类型就像是一个类似的东西c_str.如何将"分裂"部分转换为string_views?
#include <string>
#include <string_view>
#include "range/v3/all.hpp"
int main()
{
std::string s = "this should be split into string_views";
auto view = s
| ranges::view::split(' ')
| ranges::view::transform(std::string_view);
}
Run Code Online (Sandbox Code Playgroud) 我一直在研究该std::string_view库,并且一直在考虑更改我一直在努力使用的代码库std::string_view。但是,在我阅读过的许多主题中,有关何时何地使用std::string_view而不是的主题const std::string &。我已经看到许多答案说:“何时不需要以null结尾的字符串。” 因此,当我开始在网上搜索“何时需要以null结尾的字符串?”时,在这个问题上,我还没有真正有用的答案。
我可以想到一个外部库的示例,您需要链接到该外部库std::string。在那种情况下,您将需要一个以null结尾的字符串,因为该库需要它。我猜另一个例子是,如果您需要修改字符串本身,但是const &如果我们需要修改它,那么我们就不会通过。
那么什么时候需要使用以null结尾的字符串?
我看过的链接:
void Foo1(string_view view) {
...
}
string str = "one two three";
Foo1("one two three"); // Implicitly convert char* to string_view
Foo1(str);
Run Code Online (Sandbox Code Playgroud)
我想知道哪个构造函数将 char* 隐式转换为 string_view ,哪个构造函数将字符串隐式转换为 string_view ?
我知道构造函数 (4) 将 const char* 转换为 string_view 但我传递的是 char*。
虽然 aspan可以从范围构造,string_view但不能从字符范围构造。
因此,例如,需要以下代码:
// assume chars_span is a span of chars
std::cout << std::string_view(chars_span.data(), chars_span.size());
// or:
std::cout << std::string_view(chars_span.begin(), chars_span.end());
Run Code Online (Sandbox Code Playgroud)
而不是不支持的更简单的范围语法:
std::cout << std::string_view(chars_span);
Run Code Online (Sandbox Code Playgroud)
是否有理由没有string_view接受一系列字符的构造函数,或者它只是被忽视或被认为不够重要?
使用我的直觉,我认为新的 string_view 需要通过引用传递,因为这更有效(只传递指针而不是完整的类)。然而,一些消息来源表明最好按值传递它,避免“别名”问题。
在尝试几种替代方案时,我证实了我的直觉,如果该函数只是转发 string_view(所有源代码都用 编译/Ox),那么通过引用传递会更快
例如,这段代码
extern auto otherMethodByReference(const std::string_view &input) -> void;
auto thisMethodByReference(int value, const std::string_view &input) -> void
{
otherMethodByReference(input);
}
Run Code Online (Sandbox Code Playgroud)
导致了这个程序集
00000 48 8b ca mov rcx, rdx
00003 e9 00 00 00 00 jmp ?otherMethodByReference@@YAXAEBV?$basic_string_view@DU?$char_traits@D@std@@@std@@@Z ; otherMethodByReference
Run Code Online (Sandbox Code Playgroud)
虽然这段代码
extern auto otherMethodByValue(std::string_view input) -> void;
auto thisMethodByValue(int value, std::string_view input) -> void
{
otherMethodByValue(input);
}
Run Code Online (Sandbox Code Playgroud)
导致了这个程序集
00000 48 83 ec 38 sub rsp, 56 ; 00000038H
00004 0f …Run Code Online (Sandbox Code Playgroud) c++ parameter-passing compiler-optimization string-view visual-studio-2017
通常string_view用于这样的函数参数:
void fval(std::string_view sv);
void fcref(std::string_view const &sv);
Run Code Online (Sandbox Code Playgroud)
哪个更好?
const 引用是 8 个字节,string_view通常是它的两倍,例如 16 个字节。
但是,如果没有内联或优化掉,const 引用可能有两个间接引用 - 一个用于 ref,第二个用于内部指针。
STL是怎么做的?
给定某个函数void func(std::span<std::string_view>),如何const char**以最有效的方式为该函数提供原始 C 字符串数组?
据我了解,这应该是可能的,因为std::string_view可以从 C 字符串std::span构造并且可以从指针 + 大小构造,而无需任何复制。但是,我似乎无法弄清楚正确的语法。
下面是一些std::vector<std::string_view>通过迭代字符串数组中的每个字符串来创建一个的最小代码:
#include <iostream>
#include <string>
#include <span>
#include <vector>
static void func(std::span<std::string_view> strings)
{
// Just print the strings...
std::cout << "strings:\n";
for (const auto& str : strings)
std::cout << str << "\n";
std::cout << std::endl;
}
int main()
{
// Raw C string array
const char* raw_strings[3] = {
"This is a string",
"This is also a string",
"And …Run Code Online (Sandbox Code Playgroud) 我想创建一个constexpr std::array<std::string_view, ConstexprNumber>. 例如,它应该包含constexpr std::strings_view's如下内容:
"text0", "text1", "text2", ..... "textn"
我想出了以下初始解决方案:
#include <iostream>
#include <array>
#include <utility>
#include <string>
#include <string_view>
// Number of strings that we want to generate
constexpr size_t NumberOfTextsToGenerate = 10u;
// constexpr function to build a string
constexpr std::string_view makeString(unsigned int i) {
return std::string_view("text");
}
// Helper: constexpr function that will create an array of string_views and initialize it
template <unsigned int... ManyIntegers>
constexpr auto generateTextHelper(std::integer_sequence<unsigned int, ManyIntegers...>) {
return …Run Code Online (Sandbox Code Playgroud) 正如标题所述。
为什么std::string_view比较不考虑相等的内存地址。
根据标准,同样执行我检查的MSVC的STL实现。当比较两个字符串视图时,它们引用内存中相同字符串的可能性似乎被忽略,并且无论如何都会比较它们的内容。
为什么不考虑测试它们是否引用相同的字符串?