Nash Vail
Nash Vail

Reputation: 868

What to return when dequeue is called on an empty templated C++ Queue class

I have a templated Queue class in C++, with a dequeue function

template <typename el>
class Queue {
public: 
  ...
  el dequeue();
  ...
private: 

...
};

The dequeue function is defined as

template <typename el>
el Queue<el>::dequeue() {
  if(isEmpty()) {
    std::cout<<"The queue appears to be empty"<<std::endl;
    // What should I return here ? 
  } else {
   ...
  }
}

If I had a non templated class or say a simple Queue that only dealt with integers I could've returned a value like -1 or something, and stopped the execution of the dequeue function. What should I do in this case since el could be a structure, object or a primitive data type.

Upvotes: 1

Views: 3641

Answers (2)

David Haim
David Haim

Reputation: 26476

Just to add on what TartanLlama have said: the starndard library returns an iterator to the result. you can think about iterator as a wrapped pointer which used to traverse containers. when you don't have something good to return - you return a pointer to the (no-existing) one after the last element.

in your example, if Queue is done for exercise, you can return el* isntead of el as the return type of dequeue and return nullptr if you don't have something good to return.

you can also think about implementing Optional class.
the idea behind Optional is to have a wrapper class that may or may not contain a result. you implement bool operator to check if the object actually contain a valid value. a skeleton to such a class may look like:

template <class T>
class Optional{

T* m_optional;

public:

Optional(T* t);
Optional(T& t);

T* operator -> ();
operator bool() const;

};

then your return Optional<el> from Queue

of course, on real code , just use std::queue

Upvotes: 1

TartanLlama
TartanLlama

Reputation: 65600

Your best option is to just throw an exception. This signals that an error has occurred and client code can react accordingly.

Another possibility would be to return el{}; to default-construct an el. Of course, this requires el to be default-constructible, which may or may not be a reasonable constraint for you. However, this places the onus on client code to do size validation so that it can tell the difference between a dequeue on an empty Queue and a valid return equal to the default constructed el.

Upvotes: 2

Related Questions