C++临时对象生命周期延长规则及两类场景行为差异咨询
问题1 代码合法性解答
你给出的第一段代码不存在未定义行为(UB),你的相关猜测不正确。
C++标准明确规定:当临时对象被直接绑定到const左值引用或右值引用时,临时对象的生命周期会延长至与引用的生命周期一致。此处getString()返回的临时string对象直接绑定到main函数内的局部引用a,因此该临时对象的生命周期会持续到main函数执行结束、a被销毁为止,后续cout << a的访问完全合法。
只有引用是函数形参、类成员引用等特殊场景下,才不适用该生命周期延长规则。
问题2 代码合法性解答
第二段代码合法的原因和你的猜测存在偏差:string("abc")生成的临时对象作为实参传递给push_back的const T& value形参时,属于「临时对象绑定到函数形参引用」的场景,该场景下临时对象的生命周期不会延长到引用的全生命周期,仅会持续到整个函数调用表达式执行结束,也就是push_back调用完成返回的时刻。
而push_back内部的定位new操作已经在临时对象销毁前,完成了对value指向对象的拷贝构造,后续容器访问的是自身内部拷贝生成的新对象,不需要依赖原临时对象,因此整个运行行为合法。
临时对象生命周期延长的常见场景
除了最基础的「临时对象直接绑定到本地const左值引用/右值引用」场景外,符合标准的生命周期延长场景还包括:
- 范围for循环中,冒号后方的初始化表达式生成的临时对象,生命周期会延长至整个范围for循环执行结束
- 出现在
decltype、sizeof、typeid、noexcept操作数中的临时对象,不会在表达式结束后立即销毁(这类操作符本身不会对操作数求值,通常不会产生实际运行时影响) - C++20及更高版本标准中,
co_await表达式中等待器相关的临时对象,会按照协程规则延长生命周期 - 临时对象作为构造函数初始化列表中直接绑定成员引用的源对象时,部分直接构造场景下也会触发生命周期延长(注意如果是构造函数形参传入的引用绑定到成员,不会触发延长,会产生悬空引用问题)
以下常见场景不会触发临时对象生命周期延长:
- 临时对象绑定到函数形参的引用
- 临时对象绑定到类的非静态成员引用,且绑定发生在构造函数体内
- 临时对象经过中间转换、间接绑定到引用(比如先取指针再解引用绑定到引用)
- 临时对象绑定到函数返回值的引用(即常见的返回局部引用悬空问题)
内容的提问来源于stack exchange,提问作者Max Popov
相关产品推荐
相关产品推荐

