传递临时std :: string时的string_view行为

时间:2014-11-17 17:22:16

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

我刚遇到一些误解: 至少在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;
};

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

1 个答案:

答案 0 :(得分:15)

没错。 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_view是便宜的,你可以免费得到一些简洁的子串操作。相比之下,从不存储string_view ,但始终存储string

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

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