Что делать в (шаблоновом) методе извлечения стека, когда стек пуст?

Я написал шаблонный контейнерный класс, который принимает тип и шаблон параметра шаблона.

template<class type, template<typename...> class Seq>
class stack1
{
private:
    int count;
    int size;
    Seq<type> st;
    //Seq<string> str;

public:
    stack1(size_t size):size(100), count(-1){ }
    void push(type elem);
    type pop();

};


template<class type, template<typename...> class Seq>
type stack1<type, Seq>::pop()
{
    if (count < 0)
    {
        cout << "stack1 is empty," << endl;
        /*How to handle this condition.*/

    }
    else
    {
        type elem; 
        elem = st.back();
        st.pop_back();
        count--;
        return elem;
    }
}

мой вопрос: в функции pop, как мне обрабатывать сценарий ошибки, когда объект-контейнер пуст. В этом случае я хочу вернуть какое-то значение по умолчанию, например. 0/-1, если контейнер имеет тип int или ""/null, если он строковый, или 0.0, если он плавающий... что-то в этом роде.


person Bhupesh Pant    schedule 02.06.2018    source источник


Ответы (2)


Предложение @ RSahu - хорошая вещь.

Альтернативой может быть изменение подписи функции pop() с:

type pop();

to

std::optional<type> pop();

и возвращает std::nullopt, если стек пуст, или обернутое значение в обычном случае:

if (count < 0) {
    return std::nullopt;
}

Обратите внимание, что std::optional введено в стандарте языка C++17; в С++ 14 у вас есть это как std::experimental::optional, или вы можете использовать boost::optional для С++ 11 и более ранних версий.

PS: Плохая идея иметь значение count равным -1, когда количество элементов на самом деле равно 0 - очень запутанно!

person einpoklum    schedule 02.06.2018
comment
Да, я вижу это сейчас, и это выглядит именно так, как я искал. -1 просто показывает код ошибки, а -1 просто число. Но в любом случае я с вами согласен. - person Bhupesh Pant; 03.06.2018

Одним из способов справиться с этим будет создание исключения.

if (count < 0)
{
    throw std::out_of_range("stack1 is empty");
}

Я бы настоятельно не рекомендовал использовать std::cout для вывода сообщения на терминал в этом месте. Использование std::cout в реализациях структур данных является плохой практикой программирования.

person R Sahu    schedule 02.06.2018
comment
Я понимаю, что cout совсем не рекомендуется, но это просто тренировочный код. Но я согласен с вами, что исключение может быть единственным выходом. но есть ли что-нибудь, с чем мы можем справиться, используя коды возврата или что-то в этом роде. - person Bhupesh Pant; 02.06.2018
comment
@BhupeshPant, ИМО, создание исключения - лучшее решение. Вы разрешаете клиентскому коду использовать класс с помощью обычных вызовов функций, сохраняете свой код надежным и позволяете клиентскому коду обрабатывать исключение наилучшим образом. - person R Sahu; 02.06.2018