当前位置:  开发笔记 > 编程语言 > 正文

为什么std :: string_view :: data不包含空终止符?

如何解决《为什么std::string_view::data不包含空终止符?》经验,为你挑选了2个好方法。

此代码具有未定义的行为:

#include 
#include 

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
}

原因是它std::string_view可以存储非空终止字符串,并且在调用时不包含空终止符data.这是非常有限的,为了使上面的代码定义行为,我必须构建一个std::string它:

std::string str{ msg };
std::cout << str.data() << '\n';

这真是让人std::string_view在这种情况下没有必要,我还是要复制传递给字符串foo,那么为什么不使用移动语义并更改msgstd::string?这可能会更快,但我没有衡量.

无论哪种方式,std::string每次我想要传递一个const char*只接受a的函数时必须构造一个const char*有点不必要,但必须有一个理由让委员会以这种方式决定它.

那么,为什么不std::string_view::data返回一个以null结尾的字符串std::string::data呢?



1> bolov..:

那么,为什么std :: string_view :: data不返回像std :: string :: data这样的以null结尾的字符串

仅仅因为它不能.A string_view可以是较大的字符串(字符串的子字符串)的较窄视图.这意味着查看的字符串不必在特定视图的末尾具有空终止.由于显而易见的原因,您无法将空终止符写入基础字符串,并且无法创建字符串的副本并在char *没有内存泄漏的情况下返回.

如果您想要一个空终止字符串,则必须从中创建一个std::string副本.

让我好好利用std::string_view:

auto tokenize(std::string_view str, Pred is_delim) -> std::vector

这里生成的向量包含标记作为较大字符串的视图.


啊,我明白你的意思了.`std :: string_view`实际上没有缓冲区..

2> Nicol Bolas..:

其目的string_view是成为表示连续字符序列的范围.将这样的范围限制为以NUL终止符结尾的范围限制了该类的有用性.

话虽如此,让其替代版本string_view仅用于真正以NUL终止的字符串创建仍然是有用的.

我的zstring_view类是私有继承的string_view,它提供了从前端和其他操作中删除元素的支持,这些操作不能使字符串非NUL终止.它提供了其余的操作,但它们返回的是a string_view而不是a zstring_view.

你会感到惊讶的是,string_view为了完成这项工作你几乎没有什么操作可以输掉:

template>
class basic_zstring_view : private basic_string_view
{
public:
    using base_view_type = basic_string_view;

    using base_view_type::traits_type;
    using base_view_type::value_type;
    using base_view_type::pointer;
    using base_view_type::const_pointer;
    using base_view_type::reference;
    using base_view_type::const_reference;

    using base_view_type::const_iterator;
    using base_view_type::iterator;
    using base_view_type::const_reverse_iterator;
    using base_view_type::reverse_iterator;

    using typename base_view_type::size_type;
    using base_view_type::difference_type;

    using base_view_type::npos;

    basic_zstring_view(const charT* str) : base_view_type(str) {}
    constexpr explicit basic_zstring_view(const charT* str, size_type len) : base_view_type(str, len) {}
    constexpr explicit basic_zstring_view(const base_view_type &view) : base_view_type(view) {}

    constexpr basic_zstring_view(const basic_zstring_view&) noexcept = default;
    basic_zstring_view& operator=(const basic_zstring_view&) noexcept = default;

    using base_view_type::begin;
    using base_view_type::end;
    using base_view_type::cbegin;
    using base_view_type::cend;
    using base_view_type::rbegin;
    using base_view_type::rend;
    using base_view_type::crbegin;
    using base_view_type::crend;

    using base_view_type::size;
    using base_view_type::length;
    using base_view_type::max_size;
    using base_view_type::empty;

    using base_view_type::operator[];
    using base_view_type::at;
    using base_view_type::front;
    using base_view_type::back;
    using base_view_type::data;

    using base_view_type::remove_prefix;

    //`using base_view_type::remove_suffix`; Intentionally not provided.

    ///Creates a `basic_string_view` that lacks the last few characters.
    constexpr basic_string_view view_suffix(size_type n) const
    {
        return basic_string_view(data(), size() - n);
    }

    using base_view_type::swap;

    template >
    std::basic_string to_string(const Allocator& a = Allocator()) const
    {
        return std::basic_string(begin(), end(), a);
    }

    constexpr operator base_view_type() const {return base_view_type(data(), size());}

    using base_view_type::to_string;

    using base_view_type::copy;

    using base_view_type::substr;

    using base_view_type::operator==;
    using base_view_type::operator!=;
    using base_view_type::compare;
};

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有