Since you said the linked Q&A was not enough, here's my attempt. I hope it's not wrong, but it sounds plausible to me:
Your function signatures
Node* flattenLinkedList(Node* head)
Node* merge(Node* &a, Node* &b)
describe that flattenLinkedList
returns a Node*
- a pointer to a Node
. And that merge
takes a Node*
by reference. The thing about taking a reference and using it is: the referenced object should still exist by the time you use it. In your case the referenced object is a pointer.
But because c++ is weird (in other words, I do not know enough to explain this) the scope of the argument is quite short-lived. Let's say you'd split it up, like they do in this question:
{
Node* temp = flattenLinkedList(head->next);
return merge(head, temp);
}
This conceptually does the same thing, except that temp
has a clear scope: once you exit the function's {}
block by returning, temp
will no longer exist.
If you do it both in the same line though, as you have done
return merge(head, /* temp */ flattenLinkedList(head->next));
then the temp
you return from flattenLinkedList
might cease to exist immediately... This is the problem the compiler is pointing out (I think).
The linked question has a comment on this:
Note that there isn't a strict technical reason for this restriction. It would have been just as easy to implement to allow mutable references to temporaries. Forbidding it is a design decision of C++
Sidenote: what is the point of having a non-const reference as an argument if you discard temp
anyway after it is modified? You could also make the second argument of merge
a Node* b
instead of a Node* &b
, right?