1

I have been playing around with vectors and writing my own function that prints their elements. This function is straightforward to code, but I noticed a small detail which I cannot explain.

Say I have the following function that prints the elements (I'm only shown the declaration here)

void print(vector<int> vec);

And that I have another function that creates and returns a vector:

vector<int> create_vector( //parameters);

And lastly, say in my main function I wanted to run something along the lines of

print(create_vector(// some paramters)); 

I noticed this works. What also works is if I pass my vector into my print function as a constant reference:

void print(const vector<int>& vec);

However, what does not work is if I simply pass it by reference

void print(vector<int>& vec);

and I get the following error:

error: cannot bind non-const lvalue reference of type ‘std::vector&’ to an rvalue of type ‘std::vector’

I would think this is because I am trying to print a variable that has not yet been realized, but if that's the case how come it works when passed as a constant reference?

APM500
  • 85
  • 1
  • 7
  • 1
    `create_vector(...)` returns an rvalue (a temporary vector); `void print(vector& vec);` is the signature of a function that is expected to change the passed vector. However if you could pass a temporary (rvalue) then any changes would be thrown away at the end of the full expression (the `;`) when the temporary vector is deleted. Thus the compiler is helping you not make a mistake. – Richard Critten Nov 21 '21 at 21:32
  • 2
    A `const&` reference can bind to a temporary. A `&` reference cannot. A `&&` reference can bind a temporary. Which one you need to use depends on your functions contract. – Eljay Nov 21 '21 at 21:32
  • @Eljay So in effect ``const&`` creates a temporary instance of the function which is what allows you to use the print function, whereas simply passing by reference does not? – APM500 Nov 21 '21 at 21:34
  • Ahem, your question has nothing to do with printing or vectors, it is much more general: It's passing an object returned to another function as parameter. – Ulrich Eckhardt Nov 21 '21 at 21:38
  • @UlrichEckhardt Thank you, I wasn't sure how to categorize my problem but putting it under functions makes a lot more sense. – APM500 Nov 21 '21 at 21:39
  • Both create a temporary, but C++ prevents you from using a mutating reference `&` from modifying a temporary that is about to go away. Under the assumption that any mutations to the referenced parameter are intended to serve some greater purpose... so a reference to a temporary is probably a bug. – Eljay Nov 21 '21 at 21:40
  • FYI: Search for "[c++]" plus the error message, which should already give you many hits. – Ulrich Eckhardt Nov 21 '21 at 21:40
  • Your question is understood, but can you show the actual code? This signature 'void foo(std::vector& v)' shouldn't be a problem. – James Smith Nov 21 '21 at 21:48
  • Just to make my previous comment clear, you have to pass a non-constant reference to that function. Your create_vector() returns an rvalue not a reference. If you changed the print() function signature to take an rvalue reference (std::vector &&) it will work with your create_vector() function. – James Smith Nov 21 '21 at 22:28

0 Answers0