Vague about returning in a stack template

I am implementing a generic set (with an array) in C ++ and am confused about what to return in this situation:

template <class T>
T Stack<T>::pop(void) {
    if (size != 0) {
        return items[size - 1];
        size--;
    } else {
        cerr << "Cannot pop from empty stack." << endl;
        return ???;
    }
}

template <class T>
T Stack<T>::peek(void) {
    if (size != 0)
        return items[size - 1];
    else {
        cerr << "Cannot peek from empty stack." << endl;
        return ???;
    }
}

      

What are my options here? I think it would be messy to do something like declare a new variable T and return it. I am drawing a blank.

+3


source to share


2 answers


It depends on how you want the behavior (protocol) of your class. Since you are logging into the error stream there, I am assuming that you consider this an error condition to be called pop()

onto an empty stack. The standard C ++ signaling error method is exception. Something like that:

template <class T>
T Stack<T>::pop(void) {
    if (size != 0) {
        size--;
        return items[size];
    } else {
        throw std::invalid_argument("Cannot pop from empty stack.");
    }
}

      

An alternative would be to say it pop()

has a precondition, "the stack is not empty". Precondition violation is usually undefined, so you can simply assume that the stack is not empty. This is a useful approach for high performance code:

template <class T>
T Stack<T>::pop(void) {
    asssert(size > 0);  // not necessary, but it good practice to assert preconditions
    size--;
    return items[size];
}

      


The above two approaches assume that calling pop()

on an empty stack is an error, that is, it shouldn't. If you want this to be a valid operation with a well-defined result, you have several other parameters.



Returns a flag indicating success:

template <class T>
std::pair<T, bool> Stack<T>::pop(void) {
    if (size != 0) {
        size--;
        return std::make_pair(items[size], true);
    } else {
        return std::make_pair(T(), false);  // requires T to be default-constructible
    }
}

      

Return boost::optional

:

template <class T>
boost::optional<T> Stack<T>::pop(void) {
    if (size != 0) {
        size--;
        return items[size];
    } else {
        return boost::none;
    }
}

      

Revert the default built T

:

template <class T>
T Stack<T>::pop(void) {
    if (size != 0) {
        size--;
        return items[size];
    } else {
        return T();
    }
}

      

+6


source


Usually an exception is thrown in such situations.

Or, you must change the return type of the function pop

to void

.



As for the function peak

, it can return a reference to the object on the stack.

+1


source







All Articles