常量引用传递的参数由常量引用返回 我正在阅读C++ FAQ第二版,常见问题解答32.08。

常量引用传递的参数由常量引用返回 我正在阅读C++ FAQ第二版,常见问题解答32.08。,c++,C++,常见问题解答说,由常量引用传递并由常量引用返回的参数可能会导致悬空引用 但若参数是通过引用传递并通过引用返回的,那个么就可以了 我知道常量引用是不安全的,但参数为非常量引用时如何安全 FAQ的最后一行说 请注意,如果函数通过非常量引用(例如f(string&s))接受参数,则返回此引用参数的副本是安全的,因为非常量引用无法传递临时参数 需要一些关于这方面的见解 临时变量可以通过const reference传递-当函数返回临时变量时,临时变量被释放,因此调用者留下一个悬空的ref 例如: #in

常见问题解答说,由常量引用传递并由常量引用返回的参数可能会导致悬空引用

但若参数是通过引用传递并通过引用返回的,那个么就可以了

我知道常量引用是不安全的,但参数为非常量引用时如何安全

FAQ的最后一行说 请注意,如果函数通过非常量引用(例如f(string&s))接受参数,则返回此引用参数的副本是安全的,因为非常量引用无法传递临时参数


需要一些关于这方面的见解

临时变量可以通过const reference传递-当函数返回临时变量时,临时变量被释放,因此调用者留下一个悬空的ref

例如:

#include <iostream>

using namespace std;

int const& output( int const& x) 
{
    cout << x << endl;

    return x;
} 

int main ()
{
    int a = 1;

    int const& ref1 = output( a); // OK

    int const& ref2 = output(a+1); // bad

    return 0;
}
#包括
使用名称空间std;
int const&output(int const&x)
{
如果你喜欢的话

const Foo & bar(const Foo &f) { return f; }
就这样说吧

const Foo &ret = bar(Foo());
这可以编译,但问题是现在“ret”是一个悬空引用,因为通过调用Foo()创建的临时对象在bar返回后被释放。这里的详细执行顺序是:

  • 已分配临时Foo
  • 通过对临时对象的引用调用bar
  • 条返回引用
  • 既然bar已经返回,那么临时Foo就被释放了
  • 当对象被销毁时,引用现在处于悬空状态
  • 但是,如果您将Foo声明为

    Foo & bar(Foo &f) { return f; }
    

    那么编译器将不接受您的调用栏(Foo())。当您将临时对象传递给函数时,您只能通过常量引用或将其作为副本;这是语言定义的一部分。

    我认为此示例将有所帮助:

    const int& f(const int& n)
    {
        return n;
    }
    
    int f1(int& n)
    {
        return n;
    }
    
    
    int main(int argc, char **argv)
    {
        //Passing a reference to an anonymous object created by
        //the compiler to function f()
        const int& n = f(10);
    
        //Undefined behavior here as the scope of the anonymous object
        //was only till previous statement
        int k = n + 10;
    
        //Compiler error - Can not pass non-const reference to a anonymous object
        int n = f1(10);
    }
    

    是一个关于C++ 0x rValk引用的页面,引用了一个相当不错的摘要,介绍了C++和rValk如何工作在C++中,以及它们如何与引用绑定。


    大多数文章中你会发现关于C++ C++中的R值引用会给你一些了解。

    我不确定你对FAQ第二版的意思。你能把URL发布到它吗?我明白了。很多FAQ都在那里,它不在著名的在线C++ FAQ中,然后我想知道它是什么:更多信息…编辑:Ref应该是RET,所以它意味着。常量Foo&可以绑定到Foo()临时,但Foo&不能绑定到Foo()临时的。知道编译器为什么不允许这样做吗?这是不允许的,因为非ST引用必须引用命名对象。这主要是为了安全,但也有更多的理论原因。如果像int这样的非类临时值可以绑定到非ST引用,int将需要一个地址(作为对象).但它不是一个对象-只是一个值不会将临时值绑定到常量引用以延长其生存期?(cf.)