从一系列字符构造 string_view
Constructing a string_view from a range of chars
虽然 span
可以从范围构造,但 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());
而不是更简单的 range-syntax 不受支持:
std::cout << std::string_view(chars_span);
string_view
没有接受一系列字符的构造函数是否有原因,或者它只是被忽视或认为不够重要?
P1391r3 proposed this, though this was dropped in the version that was eventually adopted for C++20: P1391r4。不幸的是,论文中完全没有掉落的原因(事实上,论文甚至没有提到它被掉落)。
然而,一篇 follow-up 论文 P1989R0 提出了这个问题,如果我们有这样的类型会发生什么(我稍微修改了这个例子):
struct buffer {
buffer() {};
char const* begin() const { return data; }
char const* end() const { return data + 42; }
operator string_view() const {
return string_view(data, data + 2);
}
private:
char data[42];
};
在这里,buffer
可转换为 string_view
。但是它转换为 string_view
的方式与 string_view
的范围构造函数执行此操作的方式不同(前者给你两个字符,后者给你 42 个)。据我所知,实际上没有人指出这种类型的存在。
然而,方向是确保这些类型继续正常工作,因此新论文对特定构造函数有一组更复杂的约束。
一个更有趣的例子是这样的:
using ci_string = std::basic_string<char, case_insensitive_traits>;
ci_string value = "Hello";
std::string_view sv = value;
任何一种直接的 range-based 推理都可以将 ci_string
转换为 std::string
。 ci_string
是 char
的完美连续范围,没有任何奇怪的转换问题,如之前的 buffer
类型。但是虽然 ci_string
应该可以转换为 basic_string_view<char, case_insensitive_traits>
,但我们可能不想避免它被转换为正常的 string_view
。这不太可能是有意为之,因此我们需要努力防范。
这个案例比 buffer
案例更能激励我。
虽然 span
可以从范围构造,但 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());
而不是更简单的 range-syntax 不受支持:
std::cout << std::string_view(chars_span);
string_view
没有接受一系列字符的构造函数是否有原因,或者它只是被忽视或认为不够重要?
P1391r3 proposed this, though this was dropped in the version that was eventually adopted for C++20: P1391r4。不幸的是,论文中完全没有掉落的原因(事实上,论文甚至没有提到它被掉落)。
然而,一篇 follow-up 论文 P1989R0 提出了这个问题,如果我们有这样的类型会发生什么(我稍微修改了这个例子):
struct buffer {
buffer() {};
char const* begin() const { return data; }
char const* end() const { return data + 42; }
operator string_view() const {
return string_view(data, data + 2);
}
private:
char data[42];
};
在这里,buffer
可转换为 string_view
。但是它转换为 string_view
的方式与 string_view
的范围构造函数执行此操作的方式不同(前者给你两个字符,后者给你 42 个)。据我所知,实际上没有人指出这种类型的存在。
然而,方向是确保这些类型继续正常工作,因此新论文对特定构造函数有一组更复杂的约束。
一个更有趣的例子是这样的:
using ci_string = std::basic_string<char, case_insensitive_traits>;
ci_string value = "Hello";
std::string_view sv = value;
任何一种直接的 range-based 推理都可以将 ci_string
转换为 std::string
。 ci_string
是 char
的完美连续范围,没有任何奇怪的转换问题,如之前的 buffer
类型。但是虽然 ci_string
应该可以转换为 basic_string_view<char, case_insensitive_traits>
,但我们可能不想避免它被转换为正常的 string_view
。这不太可能是有意为之,因此我们需要努力防范。
这个案例比 buffer
案例更能激励我。