【问题标题】:string_view behaviour when passing temporary std::string传递临时 std::string 时的 string_view 行为
【发布时间】:2014-11-17 17:22:16
【问题描述】:

我只是遇到了一些误解: 至少在 libc++ 实现中 std::experimental::string_view 有以下简洁的实现:

template <class _CharT, class _Traits....>
class basic_string_view {
public:
   typedef _CharT value_type;
   ...
   template <class _Allocator>
   basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& str):
       __data(str.data()), __size(str.size())
   {
   }

private:
   const value_type* __data;
   size_type __size;
};

这个实现是否意味着如果我们将右值表达式传递给这个构造函数,我们会在构造后使用 __data 时得到未定义的行为?

【问题讨论】:

  • 是的。 string_view 只是一个美化的参考。

标签: c++ string c++11 fundamentals-ts string-view


【解决方案1】:

没错。 string_view 是具有引用语义的非拥有包装器,必须仅在引用的字符串超过视图的使用期限时使用。

典型的用例是在函数参数中,实际字符串在函数调用期间存在,函数体从不存储视图,而只是读取它:

void foo(std::experimental::string_view message)  // pass by value
{
    std::cout << "You said, '" << message << "'.\n";
}

用法:

foo("Hello");       // OK, string literal has static storage
foo(s);             // OK, s is alive
foo(s.substr(1));   // OK, temporary lives until end of full-expression

道理是:如果你只需要函数体期间的字符串,给函数一个string_view参数,它可以统一绑定到任何类型的stringoid参数。你不需要函数模板,复制string_views 很便宜,而且你可以免费获得一些简洁的子串操作。相比之下,从不存储string_view,而始终存储string

struct X
{
    X(std::experimental::string_view s) : s_(s) {}

    std::string s_;     // NEVER have a string_view class member!
};

【讨论】:

  • “从不”有点苛刻,但如果你确实存储它,那么你需要像存储“char *”时一样小心
  • @plugwash:也许吧。但是我会说,如果您存储视图,您肯定会失去消息。是的,在仅用作纯右值的瞬态类中,您可能 能够使用它,但是使用 lambda 编写此类代码可能会更好,这可以清楚地表明查看的字符串比可调用的要长。
猜你喜欢
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2021-12-29
  • 2021-12-10
  • 2021-08-11
  • 1970-01-01
相关资源
最近更新 更多