返回常量引用与临时对象
return const reference vs temporary object
我想知道为什么返回本地对象的const reference
是非法的,而返回local object
是合法的,只要您将其分配给const reference
?
vector<int> f_legal() {
vector<int> tempVec;
tempVec.push_back(1);
return tempVec;
}
const vector<int>& f_illegal() {
vector<int> tempVec;
tempVec.push_back(1);
return tempVec;
}
void g() {
const vector<int>& v1 = f_legal(); // legal
const vector<int>& v2 = f_illegal(); // illegal
}
编辑:我的观点是,如果
返回对局部变量的引用是非法的(未定义的行为(。时期。没有const
或mutable
条款。
这是因为局部函数变量具有自动存储持续时间。它们在函数退出后被"销毁"。如果函数返回对此类变量的引用,则该引用称为悬空:它引用不再存在的对象。
第一个是合法的,因为有一个特殊的C++规则:初始化对prvalue
的引用会将该临时对象的生存期延长到引用的生存期。
即使你把它分配给一个 const 引用,返回值也会声明为按值传递,这意味着它将作为临时对象被复制到外部[1],然后绑定到 const 引用。将临时对象绑定到 const 引用很好,在 const 引用的生命周期之外,该对象不会被销毁。
另一方面,返回局部变量的引用是 illegel。当函数返回时,局部变量将被销毁,这意味着外部引用将被悬空。
编辑
我的观点是,如果将常量引用分配给返回的局部变量是合法的,那么将常量引用分配给局部变量的返回的常量引用是否也是合法的?
关键是第一种情况不是将常量引用分配给返回的局部变量,而是将常量引用分配给返回的临时变量。(可能从局部变量复制。
[1] 根据 RVO 技术上,可以省略该副本。
很可能是因为它会完全破坏几十年来一直为我们服务的整个基于堆栈的调用约定......几乎每个 CPU 都假设。
相关文章:
- 为什么当我们有常量引用时创建临时对象?
- 返回对临时对象的引用
- 通过引用传递临时对象
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 对临时对象的Const引用不会延长其生存期
- 为什么引用类型在使用临时对象访问时是左值
- 取消引用临时对象上的运算符
- 常量引用函数参数:是否可以禁止临时对象?
- 为什么临时对象可以绑定到常量引用?
- 为什么常量引用不能延长通过函数传递的临时对象的生存期?
- 使用常量引用延长临时对象的寿命
- 从函数返回引用是否会导致在使用'auto'时创建新的临时对象?
- 关于将临时对象传递给常量引用
- 将临时对象绑定到常量引用
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)
- 返回对本地临时对象 C++ 的引用
- 模板类型推导警告返回对本地临时对象的引用
- 为什么不对临时对象进行非常量引用
- 堆上是否会分配内存以支持临时对象到常量引用的嵌套绑定
- 传递给存储常量引用的成员的临时对象的生存期