I'll try and give some quick answers to Q1, Q2 and Q3 (but by no means complete, you should research the terms used to get a better understanding). Like the comments suggest, the rest a more suited for Code review.
Q1 - A) Since the reference is constant, the compiler is able to bind the literal to the parameter. The line of thought is, if the function can't modify it, then it is irrelevant whether or not the object*/primitive is defined or a literal. If the signature was push(value_type & value)
, then this would not work. This function is expecting a non-constant reference to an object/primitive which would allow you to modify it. This does not make sense since as you cannot modify a literal, and as such is not allowed.
B) Yes enqueue(Queue const & value)
will add deep copies but no the function should not take a copy of value. If it did, you would be copying all the items 2 times instead of 1 time. The function enqueue(Queue const value)
(taking a copy) would first construct a new queue value
from the parameter you give the function (see copy constructor). Then go through value
and add new elements to the front of the calling Queue with the value of those in value
. Thus every item would be copied twice, when the parameter value is constructed and when the items are added to the calling Queue.
Q2 - As explained in the comments value_type && value
is a forwarding reference or an r-value reference. More or less a reference to a value that has not been binded to a l-value. This enables you to efficiently do things like push(MyObject(1, 2, 3))
(as MyObject(1, 2, 3)
has not been bound to a 'l-value') or to pass ownership. (see move constructor)
Q3 - const T & front() const
The first const
refers to the return type (T&), the second const
refers to the calling Object (Queue). front
returns a reference to the first element in the queue. T & front()
enables you to get the first element and modify it through the reference (Yes modifying the front of a queue is useful in some cases). But if the Queue is constant, then getting the first element and modifying it wouldn't make sense. So you give the user an alternative for using on const Queue's, const T & front() const
. You still get a reference to the front of the Queue, but the reference is const qualified so you cannot modify it. As per the compiler - const T & front() const
is for const Queue and T & front()
is for normal Queue.