0

QUESTIONS:

  1. I used the template described on cppreference.com to guide me in the implementation of some of the functions, such as push() (enqueue() in my case). On cppreference.com, the following templates are given:

     (a) push(const value_type & value);
     (b) push(value_type && value);
    

https://en.cppreference.com/w/cpp/container/queue/push

Since (a) takes a reference, how is it that literals are added to the queue?

Moreover, if I implement a function

         enqueue(Queue const & other) 

using the function

         enqueue(T const & value) 

by iterating through "other" and enqueuing every value in "other," will this not add "deep" copies of the values in "other?" And, therefore, I should not pass a reference to other, but a copy?

  1. Moreover, what is the meaning of "&&"?

  2. How are the two functions

     (a) const T & front() const
     (b) T & front()
    

differentiated by the compiler? Moreover, that (a) has a const after the function's name means that an outside user will not be able to modify the front variable? Would you even want to modify the front (or end) variable of a queue?

Thank you for your time!

  • Questions are best kept to one question per question. 1 and 2 are suitable for asking here, maybe even in the same question, 3 through 6 are better fits for [Code Review](https://codereview.stackexchange.com/help/asking). Yes, I did deliberately link to the How To Ask help page. – user4581301 Apr 05 '19 at 04:03
  • That said what you have looks decent to a quick glance. I would not implement random access `[]` operators on a queue. Queues only allow insertion at one end and extraction from the other, so random access is not queueish. – user4581301 Apr 05 '19 at 04:04
  • Hey, user458. Thank you for your feedback. I will go over that page. I did consider separating the questions. But, it felt tedious posting my code on several separate posts. Moreover, I thought I had marked my question as "code review." Excuse me since I did not! Thanks again :) – Rafael Vergnaud Apr 05 '19 at 04:12
  • I realize now that code review is an entirely separate forum (excuse me). – Rafael Vergnaud Apr 05 '19 at 04:16
  • No worries. The loose rule of thumb is code that doesn't work goes here. Code that does work, but could work better, goes to Code Review. A note on 2) `value_type && value` is a [forwarding reference](https://en.cppreference.com/w/cpp/language/reference#Forwarding_references) (sometimes called a universal reference). Most often you will find these where transfers of [ownership](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) are taking place with `std::move`. – user4581301 Apr 05 '19 at 04:18
  • Alright. I think that is beyond me at the moment, so I may remove that function! I also removed the random access functions. Makes sense that way, certainly. Thanks user! – Rafael Vergnaud Apr 05 '19 at 04:26

1 Answers1

0

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.

Bar Stool
  • 620
  • 3
  • 13
  • 1
    Addendum to 3: Overloads are selected based how well the calling arguments match the function's parameters. [Grisly details](https://en.cppreference.com/w/cpp/language/overload_resolution). A simplistic view of a member function (that often pans out) is `T & Queue::front()` is actually `T & front(Queue *)` to pass in the `this` parameter. `T & Queue::front() const` means `this` is `const`, so `T & front(const Queue *)`. The function parameters are now different and the correct overload can be called. – user4581301 Apr 05 '19 at 15:02
  • May I ask a few further questions? (1) Why would one declare Queue a const? Is it not the case that a const Queue cannot be modified, i.e., cannot have elements added to or removed from it, thereby rendering the queue useless? – Rafael Vergnaud Apr 05 '19 at 15:23
  • (2) Is it not a better idea to add a copy of the elements in the other queue? If I am adding references, then does not my copy constructor, which should be making shallow copies, not work properly? – Rafael Vergnaud Apr 05 '19 at 15:24
  • I also removed all the questions after 3, and moved those to Code Review per your suggestion. – Rafael Vergnaud Apr 05 '19 at 15:25
  • @RafaelVergnaud you could still peek at the one available element and, because a `const` reference can extend the life of a temporary, you could pass a temporary along until you reach a point where you do store it permanently. Other people may have more insights, so this could be a good stand-alone question. Copy constructor will work just fine with references. You can deep or shallow copy a reference (and you can surprise the hell out of people by transferring ownership, something I don't recommend. Use `&&` if you want to transfer ownership). – user4581301 Apr 05 '19 at 16:56
  • Ah, ok. Thanks user :) – Rafael Vergnaud Apr 05 '19 at 21:31