【发布时间】:2021-11-07 23:03:10
【问题描述】:
假设我有以下代码:
void some_function(std::string_view view) {
std::cout << view << '\n';
}
int main() {
some_function(std::string{"hello, world"}); // ???
}
view 内的some_function 是否会指代已被销毁的string?我很困惑,因为考虑到这段代码:
std::string_view view(std::string{"hello, world"});
产生警告(来自clang++):
warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl]
有什么区别?
(奇怪的是,使用大括号{} 而不是括号() 来初始化上面的string_view 消除了警告。我也不知道为什么会这样。)
说清楚,我理解上面的警告(string_view 比string 寿命长,所以它有一个悬空指针)。我要问的是为什么将string 传递给some_function 不会产生相同的警告。
【问题讨论】:
-
临时值的生命周期是直到完整表达式结束。在第一个示例的情况下,完整表达式的结尾是
some_function调用完成时。所以在这种情况下它是有效的。 -
clang 发出警告是正确的。
std::string_view view(std::string{"hello, world"});创建一个 string_view ,如果你想避免未定义的行为,你绝不能访问它的数据,因为view引用的 char 数组在完整表达式的末尾消失了。另一种用法会起作用,因为临时字符串会一直存在,直到some_function返回。 -
如果将参数类型从
std::string_view view更改为const std::string_view& view,编译器警告会消失吗? -
@fabian 谢谢,但为什么
std::string_view view{std::string{"hello, world"}}(即带大括号)没有产生警告?
标签: c++ c++17 stdstring string-view