简体   繁体   English

如何解决 C++ std::string_view 范围外问题?

[英]How to work around C++ std::string_view out-of-scope problem?

In the following article under the section "Ownership Issues", it mentions that if someone sets up a std::string_view to look at a std::string variable then leaves the scope of that std::string, the std::string_view's behavior will be undefined.在“所有权问题”部分下的以下文章中,它提到如果有人设置 std::string_view 来查看 std::string 变量然后离开该 std::string 的范围,则 std::string_view 的行为将是未定义的。

https://www.learncpp.com/cpp-tutorial/6-6a-an-introduction-to-stdstring_view/ https://www.learncpp.com/cpp-tutorial/6-6a-an-introduction-to-stdstring_view/

I understand that this is caused by the fact that the std::string variable is no longer in scope and "dies", so what's being viewed by the std::string_view is undefined.我知道这是由于 std::string 变量不再在范围内并且“死亡”这一事实造成的,所以 std::string_view 正在查看的内容是未定义的。 How would one work around this?如何解决这个问题?

My current function does something to this effect:我当前的函数对这个效果做了一些事情:

std::string_view mergeIntoSV(std::string str1, std::string str2) {
  std::string new_str = str1 + str2;
  return std::string_view { new_str };
}

void callMerge() {
  std::string list[10];
  std::string_view views[5];
  //Assume some code that populates "list"...
  for (int i = 0; i < 10; i+=2) {
    views[i/2] = mergeIntoSV(list[i], list[i+1]);
  }
  //Now I want to be able to read each of the std::string_views.
}

However, after invoking this function elsewhere and then reading the contents of returned std::string_view, I (as the article suggests) read some undefined string value.然而,在别处调用这个函数然后读取返回的 std::string_view 的内容后,我(如文章所建议的)读取了一些未定义的字符串值。 Unfortunately I can't simply change the return type to std::string due to the fact that I'm working a larger codebase and required the return type to be as is.不幸的是,我不能简单地将返回类型更改为 std::string,因为我正在使用更大的代码库并要求返回类型保持原样。

How does one work around this out-of-scope problem?如何解决这个超出范围的问题?

You are creating an string object in a conceptually pure function (no state outside of the inputs/outputs).您正在概念上的纯函数中创建一个字符串对象(输入/输出之外没有状态)。 You then decided that this pure function should return a non-owning view of this object.然后你决定这个纯函数应该返回这个对象的非拥有视图。 This is a contradiction: a pure function cannot own state after the function has completed execution.这是一个矛盾:纯函数在函数完成执行后不能拥有状态。 And if the function doesn't own that state, and the return value doesn't own that state... the state doesn't exist.如果函数不拥有该状态,并且返回值不拥有该状态......该状态不存在。

You have only two options: return something that actually owns the string, or make the function non-pure by having it creating a string which outlives the function call (this could be through a static local, a global, or any number of things).您只有两个选择:返回实际拥有该字符串的内容,或者通过创建一个比函数调用寿命更长的字符串来使函数变得非纯(这可以通过静态局部、全局或任意数量的事物) . The latter is almost always the wrong answer.后者几乎总是错误的答案。

If some larger codebase required this operation, then that larger codebase has a design problem that needs to be resolved.如果某个较大的代码库需要此操作,则该较大的代码库存在需要解决的设计问题。

A string view isn't magical: Essentially, it's just a pointer to the start of the string, and its length.字符串视图并不神奇:本质上,它只是一个指向字符串开头及其长度的指针。 Just like you wouldn't return a pointer to a local variable, you wouldn't return an std::string_view to a local string.就像您不会返回指向局部变量的指针一样,您也不会将std::string_view返回到本地字符串。 It's that simple.就这么简单。

The "solution" is the same as for pointers: “解决方案”与指针相同:

  • If the (string) object should be local - don't return a pointer (string view) to it.如果(字符串)对象应该是本地的 - 不要返回指向它的指针(字符串视图)。
  • If the (string) object lifetime should to extend the lifetime - either:如果(字符串)对象生命周期应该延长生命周期 - 要么:
    • return by value (there's guaranteed return-value copy elision and NRVO ), or按值返回(有保证的返回值复制省略NRVO ),或
    • create a buffer through, say, an std::unique_ptr , and then move-return it, or例如,通过std::unique_ptr创建一个缓冲区,然后移动返回它,或者
    • pass a buffer to work with as input, and use that for your string data.传递一个缓冲区作为输入,并将其用于字符串数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM