【问题标题】:Constructing a string_view from a range of chars从一系列字符构造 string_view
【发布时间】:2021-01-21 12:28:19
【问题描述】:

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

【问题讨论】:

    标签: c++ c++20 string-view


    【解决方案1】:

    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::stringci_stringchar 的一个非常好的连续范围,没有任何奇怪的转换问题,例如之前的 buffer 类型。但是虽然ci_string 应该可以转换为basic_string_view&lt;char, case_insensitive_traits&gt;,但我们可能不想避免它可以转换为普通的string_view。这不太可能是故意的,因此我们需要努力防范。

    这个案例比buffer 案例更能激励我。

    【讨论】:

    • 我相信任何获得范围的函数都会出现类似的问题,例如获取范围的span 的构造函数。
    • 这太可怕了。如果我不得不考虑这些怪癖,我会(害怕)死去。
    • @AmirKirsh span 在 C++20 之前不存在,所以这不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2021-01-23
    相关资源
    最近更新 更多