从一系列字符构建 string_view

Ami*_*rsh 7 c++ string-view c++20

虽然 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接受一系列字符的构造函数,或者它只是被忽视或被认为不够重要?

Bar*_*rry 5

P1391r3提出了这个,尽管它在最终被 C++20 采用的版本中被删除了:P1391r4。不幸的是,论文中完全没有掉落的原因(事实上,论文甚至没有提到它被掉落)。

但是,后续论文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];
};
Run Code Online (Sandbox Code Playgroud)

在这里,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;
Run Code Online (Sandbox Code Playgroud)

任何类型的基于范围的简单推理都允许从ci_string到的转换std::string。Aci_string是 的一个非常好的连续范围char,没有任何奇怪的转换问题,如之前的buffer类型。但是,虽然ci_string应该可以转换为basic_string_view<char, case_insensitive_traits>,但我们可能不想避免将其转换为普通string_view。这不太可能是故意的,所以这是我们需要努力防范的。

这个案子对我来说比这个buffer案子更有动力。

  • 太可怕了。如果我不得不考虑这些怪癖的话,我会(害怕)死去的。 (2认同)