wei
wei

Reputation: 6889

Difference between reference and const reference as function parameter?

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 ?

Upvotes: 6

Views: 10119

Answers (5)

Jeffrey Chu
Jeffrey Chu

Reputation: 1

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.

Upvotes: 0

stefanB
stefanB

Reputation: 79790

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.

Upvotes: 0

Donotalo
Donotalo

Reputation: 13025

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.

Upvotes: 0

P Shved
P Shved

Reputation: 99264

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.

Upvotes: 0

gdunbar
gdunbar

Reputation: 601

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.

Upvotes: 6

Related Questions