6

Here is a simple snippet of C++ code:

A foo(){
  A a; // create a local A object
  return a;
}

void bar(const A & a_r){

}

bar(foo());

Why does the argument of function bar have to be a const reference,not just a reference?

Edit1: I know that reference is to avoid copying overhead. and const is for read-only. But here I have to make it a const reference, otherwise if I remove the "const", g++ will throw an error to me.

Edit2: My guess is that the return object of foo() is a temporary object, and it's not allowed to change the value of a temporary object ?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
wei
  • 6,629
  • 7
  • 40
  • 52
  • Its the function itself determine whether its arguments should be const or not.In other word,you should provide the content of bar. – Jichao Nov 12 '09 at 04:11

5 Answers5

6

Without the error message, I'm not exactly sure what the compiler might be complaining about, but I can explain the reason logically:

In the line:

bar(foo()); 

The return value of foo() is a temporary A; it is created by the call to foo(), and then destructed as soon as bar() returns. Performing a non-const operation (i.e. an operation that changes the temporary A) doesn't make sense, as the object A is destructed right afterwards.

Looking a little more, this is a virtual dup of this question:

How come a non-const reference cannot bind to a temporary object?

which has an excellent answer.

Community
  • 1
  • 1
gdunbar
  • 571
  • 4
  • 11
  • A copy of object of class A is returned, and that will be visible withing bar(). – Donotalo Nov 12 '09 at 04:20
  • Thanks, that was my guess actually :). So it's illegal only because changing temporary object doesnt' make sense? – wei Nov 12 '09 at 04:21
  • wei - That's right, the C++ standard frowns on changing temporary objects. Again, the question I linked has a much better explanation than I can write. :-) – gdunbar Nov 12 '09 at 04:25
0

The reference has to refer to const object because you won't be able to utilize changes to it anyway. Compare the following code snippets:

void bar(A&);   
A x = foo();
bar(x);
if (x.member) {...} else {...}

and

void bar(A const&);   
bar(foo());
if (//x? we don't have any x! We can't branch here!

While in the first example, the ability to modify the object may significantly alter the execution of the consequent code, in the second one we just don't have the means (variable name we could refer to) to do it. Therefore, we can only use the reference to const, which wants the object to be not modified.

P Shved
  • 96,026
  • 17
  • 121
  • 165
0

Why does the argument of function bar have to be a const reference,not just a reference?

The argument of bar() need not be const reference. But when passing objects to function parameter, it is the most efficient way when the object will not be modified by the function.

  • Making a parameter constant guarantees that the compiler wil issue warning when you try to modify the object.
  • Passing a parameter as reference will not create a copy of the object and hence efficiency is achieved.
Donotalo
  • 12,748
  • 25
  • 83
  • 121
0

Compiler is looking for bar(const foo&) because you are passing const reference to foo into bar in bar(foo()) - this is because you are passing reference to a temporary variable which will not exist once bar returns.

There is no use case where it makes sense to modify foo inside bar via the reference because it will not exist once you return from bar().

So compiler enforces this to prevent hiden bugs where developer passes reference to temporary and updates the temporary object which will disappear after method returns.

stefanB
  • 77,323
  • 27
  • 116
  • 141
0

the code bar(foo()) is passing a lvalue to bar(). only rvalue can have a pointer or reference to it. lvalue can have a const reference to it because the const restriction prevent an assignment operation to a non-existing lvalue.