有没有办法制作一个引用外部提供的缓冲区但不拥有它的 std::string ?

pet*_*erk 15 c++ string reference zero-copy

基本上,如果一个人有一个用于空终止字符串的预加载缓冲区和要引用的长度,并且想要将对它的引用传递到一个采用 std::string & 但不复制该字符串或拥有它的方法中,是吗?可能这样做吗?

这只具有有限的寿命,并且以仅在缓冲区有效时才有效的方式进行管理。

eer*_*ika 12

有没有办法制作一个引用外部提供的缓冲区但不拥有它的 std::string ?

不。

您有以下选择:

  1. std::string首先用作“外部”缓冲区。
  2. 将外部缓冲区复制到字符串中。
  3. 不要使用(引用)std::string作为参数。
    • std::string_view是一个典型的不错的选择。但是,创建非空终止字符串视图非常容易,并且您的前提明确声明空终止。如果这很重要,那么您可能需要避免字符串视图。
    • 如果字符串视图不合适,那么您可以使用const char*指向以空字符结尾的字符串。

  • @Caleth这完全取决于函数用它做什么。`std::string` 也是以 null 结尾的。 (3认同)

Ant*_*ier 2

基本上,对于非拥有字符串来说,答案是否定的。

但是,如果非拥有标准不是那么重要,您可以做的是使用您自己的分配器来引用特定的缓冲区。

您还可以做的是使用std::pmr::string它允许您提供自定义memory_resource.

想法如下:

#include <string>
#include <memory_resource>
#include <array>
#include <utility>
#include <iostream>

template<std::size_t size>
class StackBufferResource {
    public:
        auto as_resource() {return &m_resource;}
        auto address() {return m_buffer.data();}
    private:
        std::array<std::byte, size> m_buffer{};
        std::pmr::monotonic_buffer_resource m_resource{m_buffer.data(), size};
};

int main() {
    StackBufferResource<512> buffer;

    std::pmr::string myString("My name is Antoine and I am not sure for this answer", buffer.as_resource());
    std::cout << myString << "\n";
    std::cout << (const char*)buffer.address() << std::endl;
}

Run Code Online (Sandbox Code Playgroud)

std::pmr::monotonic_buffer_resource是一个memory_resource不断生长的物体。这意味着释放是一种“无操作”。

这样的东西的好处是你可以将同样的东西赋予std::pmr::vector.

不过,您可以注意以下几点:

std::pmr::string使用char。由于它是一个微不足道的对象,我认为(但我不确定)在字符串被破坏后访问缓冲区内存是安全的。如果它是一种不易破坏的类型,我认为有可能看到垃圾值。