简体   繁体   中英

Parameter passed by const reference returned by const reference

I was reading C++ Faq Second Edition, faq number 32.08.

FAQ says that parameter passed by const reference and returned by const reference can cause dangling reference.

But it is ok if parameter is passed by reference and returned by reference.

I got it that it is unsafe in case of const reference but how is it safe in case when parameter is non const reference.

Last line of FAQ says "Note that if a function accepts a parameter by non-const reference (for example, f(string& s)), returning a copy of this reference parameter is safe because a temporary cannot be passed by non-const reference."

Need some insight on this!!

if you have like

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

and call it like

const Foo &ret = bar(Foo());

This compiles, but the problem is that now 'ret' is a dangling reference, because the temporary object created by the call to Foo() gets freed after bar returns. The detailed execution sequence here is:

  1. temporary Foo is allocated
  2. bar is called with a reference to the temporary object
  3. bar returns the reference
  4. now that bar has returned the temporary Foo is released
  5. the reference is now dangling as the object was destroyed

However, if you had Foo declared as

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

then your call bar(Foo()) would not be accepted by compiler . When you pass a temporary object to a function, you can only take it by const reference or as a copy; this is part of the language definition.

Temporaries can be passed by const reference - when the function returns the temporaries are destoyed, so the caller is left with a dangling ref.

For example:

#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;
}

I think this example will be helpful:

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);
}

Here is a page about C++0x rvalue references that starts with a pretty decent summary of how lvalues and rvalues work in C++, along with how they are allowed to bind with references.

Most articles you will find about rvalue references in C++0x will give you some insight into this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM