8

虽然 aspan可以从一个范围构造,但 astring_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());

而不是不支持的更简单的范围语法

std::cout << std::string_view(chars_span);

有没有理由没有一个构造函数来string_view接受一系列字符,或者它只是被忽略或被认为不够重要?

4

1 回答 1

6

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];
};

在这里,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;

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

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

于 2020-10-06T15:37:21.630 回答