C++ 返回常量引用与临时对象

C++ 返回常量引用与临时对象,c++,reference,constants,C++,Reference,Constants,我想知道为什么返回本地对象的常量引用是非法的,而返回本地对象是合法的,只要您将其分配给常量引用 vector<int> f_legal() { vector<int> tempVec; tempVec.push_back(1); return tempVec; } const vector<int>& f_illegal() { vector<int> tempVec; tempVec.push_b

我想知道为什么返回本地对象的
常量引用
是非法的,而返回
本地对象
是合法的,只要您将其分配给
常量引用

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
}
向量f_legal(){ 向量tempVec; tempVec.推回(1); 返回tempVec; } 常量向量&f_非法(){ 向量tempVec; tempVec.推回(1); 返回tempVec; } void g(){ 常量向量&v1=f_legal();//legal 常量向量&v2=f_非法();//非法 } 编辑:
我的观点是,如果将const ref分配给返回的局部变量是合法的,那么将const ref分配给返回的局部变量const ref不也是合法的吗?

返回对局部变量的引用是非法的(未定义的行为)。时期没有
const
mutable
子句

这是因为局部函数变量具有自动存储持续时间。它们在函数退出后被“销毁”。如果函数返回对此类变量的引用,则该引用称为悬空引用:它引用的对象不再存在


第一个是合法的,因为一个特殊的C++规则:初始化对一个引用的引用> PROVALUT/COD>将该临时对象的生存期延长到引用的生存期。

< P>即使将它分配给一个const引用,返回值也被声明为值传递,这意味着它将被复制到[4]作为临时对象,然后绑定到常量引用。将临时对象绑定到常量引用是可以的,该对象在超出常量引用的生存期之前不会被销毁

另一方面,返回局部变量的引用是错误的。当函数返回时,局部变量将被销毁,这意味着外部引用将被挂起

编辑

我的观点是,如果将const-ref分配给返回的局部变量是合法的,那么将const-ref分配给返回的局部变量const-ref不也是合法的吗

重点是第一种情况不是将const ref分配给返回的局部变量,而是将const ref分配给返回的临时变量。(可能是从局部变量复制的。)



[1]根据RVO技术,该副本可能会被省略。

< P>最有可能是因为它会彻底破坏几十年来为我们服务的整个堆栈调用约定……几乎每个CPU都假设。

@ ED愈合:是的,C++中定义良好,本地const引用将延长它的临时生存期。约束。@EdHeal是的,这是合法的。标准中有一种特殊情况,只要当前作用域中存在对本地对象的常量引用,它就会保持本地对象的活动状态。您确定总是这样吗?甚至考虑到
RVO/NRVO
?@JamesAdkison:将有一个临时对象,引用将绑定到该临时对象。副本可能会被删除(如果结果可以直接在临时文件中构建)。@BenVoigt是的,这是我的观点(即副本可以被删除)。@JamesAdkison afaik RVO作为优化不会改变任何规则。“规则”是:返回值是按值传递的(即复制的),这不是为什么会出现这种情况的问题吗?规则实际上与
const
无关——任何直接绑定到临时对象的引用都会延长该临时对象的生存期。在C++98中,其他规则规定只有常量引用可以直接绑定到临时变量,这些规则现在已经更改,这对生存期扩展规则产生了多米诺骨牌效应。@BenVoigt这是我第一次听到这个。你能提供一份推荐信吗?@BenVoigt谢谢你。这非常有用。@Maggyero:这不是直接绑定到临时文件的引用,而是编译错误。但是
int&&r=3
进行编译,并延长了临时文件的生存期。@Maggyero:您还可以从类型不匹配或其他限定符不匹配中获得引用绑定编译错误,例如尝试在不执行常量转换的情况下删除volatile。如果我说引用是直接绑定的,那么很自然地,我所说的只是可能的场景。