Experimental::basic_string_view<> 是否适用于右值?

vso*_*tco 6 c++ c++11 string-view c++17

我并不 100% 认为以下代码在语义上是正确的:

#include <iostream>
#include <experimental/string_view>

int main()
{
    std::string str = "lvalue string";

    std::experimental::string_view view_lvalue(str);
    std::experimental::string_view view_rvalue(std::string{"rvalue string"});

    std::cout << view_lvalue << '\n' << view_rvalue << '\n';
}
Run Code Online (Sandbox Code Playgroud)

Live on Wandbox

问题:我可以合法地将右值绑定到std::experimental::basic_string_view,还是只是 UB?如果是,它是如何运作的?据我所知,右值不会const通过构造函数绑定到引用(我假设视图保存原始字符串),所以我认为在语句末尾,std::experimental::string_view view_rvalue(std::string{"rvalue string"});引用将是悬空的。是否string_view使用更复杂的方法?

我问这个问题是因为我正在尝试为某些矩阵类编写类似的视图,并且还不知道如何处理右值(我当然可以禁用它们,但我认为这不是最好的方法)。

Nat*_*ica 3

如果 cppreference 正确,则这就是 UB。 std::string_view

典型的实现仅包含两个成员:指向常量的指针CharTsize.

并且构造函数有

str.size()构造从 指向的元素开始的字符数组的第一个字符的视图str.data()

因此,如果string_view仅指向所提供字符串的底层 char 数组,那么一旦表达式结束并且临时对象被销毁,我们将得到一个悬空指针。

正如评论中指出的,这种行为可能被允许的原因之一是,您可以将 a 传递string_view给函数并string_view从临时构造函数string

  • @vsoftco 是的,但仔细想想,禁止右值可能会显着降低采用字符串视图参数的函数的可用性。 (3认同)
  • @vsoftco 右值应该存在到表达式末尾,并且让函数执行和返回是表达式的一部分,因此右值应该始终处于活动状态。 (3认同)
  • 请注意,[类似的 GSL 类型 `string_span`](https://github.com/Microsoft/GSL) 明确禁止在各种情况下使用右值,正是出于这个原因。当然,正如 TC 指出的那样,这在某些情况下很难使用;你必须创建一个显式的临时文件。 (2认同)