如何使用 std::string 或其等效项包装字符的普通缓冲区?

How do I wrap a plain buffer of char's with an std::string or an equivalent thereof?

本文关键字:字符 包装 缓冲区 std 何使用 string      更新时间:2023-10-16

动机:

我正在使用一些具有以下功能的库(我不控制(:

char* foo(/*some parameters here */);

它返回一个非常长的、以null结尾的字符串。现在,我想使用功能

void bar(const std::string& s);

它在我正在使用的另一个库中可用(也就是说,我不控制这两个函数的签名(。我想将foo()的结果传递给bar()-而不复制它。

问题:

我想用字符串对象包装一个连续的字符缓冲区,这样它就可以作为const std::string&传递。我该怎么做?

注意:

  • 我意识到这可能会让人反感,但如果可能的话,我无论如何都想这么做
  • 是的,这可能不合适,或者丑陋,或者过于C型——但这正是我(认为我(需要做的
  • 对答案的评论表明,继承std::string不是一种选择,因为它没有合适的虚拟方法。这基本上让我们对实现进行假设(或为不同的实现编写不同的代码(,并"手动构建"std::string实例。因此,问题似乎是如何做到这一点

不,你不能。审查您的需求并消除此需求。

您可以使用boost::string_ref来模拟它。

  • http://www.boost.org/doc/libs/1_55_0/libs/utility/doc/html/string_ref.html

它有一个可与std::string:互操作的接口

boost::string_ref s = "hello world";
std::string compareto = "bye world";

bool test = (compareto != s);

当然,只有当您可以在界面中选择接受string_ref而不是string时,这才会起作用。这样,您就可以在空闲时传递c字符串或std::字符串,这样做是正确的。

老问题,但从C++17开始,您现在有了std::string_view,这正是适合该作业的工具。

只需将其初始化为:

auto my_string_view = std::string_view(foo(whatever));

并在任何使用std::string const的地方使用它。或者,如果你需要制作一个非常量的副本,你可以简单地用初始化一个临时字符串

auto my_new_string = std::string{my_string_view}

您不能这样做,但您可以轻松地编写自己的字符串类。由于您明确禁止对其进行任何复制,因此您甚至不需要支持许多std::string类型的操作,如串联等。

(理论上,您可以通过创建缓冲区的内部树来支持级联而无需复制,但这将是更多的工作。(