如何使用std :: string或其等价物包装char的普通缓冲区?

时间:2014-05-03 14:29:00

标签: c++ string wrapper idiomatic

动机:

我使用了一些库(我无法控制),具有以下功能:

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

返回一个非常长的以null结尾的字符串。现在,我想使用函数

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

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

问题:

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

备注:

  • 我意识到这可能是不赞成的,但无论如何我都想这样做,如果可能的话。
  • 是的,这可能是不恰当的,或丑陋的,或者太像C样 - 但它是我(我想)需要做的事情。
  • 对答案的评论表明,继承std::string不是一种选择,因为它没有适当的虚拟方法。这基本上让我们假设有关实现的事情(或为不同的实现编写不同的代码),以及“手工构建”#39;一个std::string个实例。因此,问题似乎是关于这样做。

4 个答案:

答案 0 :(得分:4)

不,你不能。检查您的要求并消除对此的需求。

答案 1 :(得分:3)

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

它有一个可与std :: string:

互操作的接口
boost::string_ref s = "hello world";

std::string compareto = "bye world";


bool test = (compareto != s);

当然,只有您可以在界面中选择接受string_ref而不是string时,此功能才有效。这样,你可以在闲暇时传递c-strings或std :: strings,它会做正确的事。

答案 2 :(得分:2)

老问题,但是从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}

答案 3 :(得分:0)

你不能这样做,但你可以轻松地编写自己的字符串类。由于您明确禁止制作它的任何副本,因此您甚至不需要支持许多std :: string类型的操作,例如连接等。

(理论上,您可以通过创建缓冲区的内部树来支持连接而不进行复制,但这样做会更有效。)