C ++, перехват исключений разных типов данных

0

Моя проблема в том, что у меня есть класс шаблона, и я пытаюсь поймать исключения из разных типов данных (int, float, long, char и т.д.).

#include <iostream>
using namespace std;

const int MAX = 3;

template<class Type>
class Stack()
{
    class Range{};
    class Empty{};
    class Input{};

    //Code here
    //Code here
    //If Error: 
    throw Range();
    throw Empty();
    throw Input();
}

int main()
{
    try
    {
        Stack<int> s1
        Stack<float> s2
        Stack<long> s3
        Stack<char> s4
    }
    catch(Stack<int>::Range)   { //Code }
    catch(Stack<float>::Range) { //Code }
    catch(Stack<long>::Range)  { //Code }
    catch(Stack<char>::Range)  { //Code }
    catch(Stack<int>::Empty)   { //Code }
    catch(Stack<float>::Empty) { //Code }
    catch(Stack<long>::Empty)  { //Code }
    catch(Stack<char>::Empty)  { //Code }
    catch(Stack<int>::Input)   { //Code }
    catch(Stack<float>::Input) { //Code }
    catch(Stack<long>::Input)  { //Code }
    catch(Stack<char>::Input)  { //Code }

return 0;
} 

Как я мог сделать то же самое в 3 строках? Я пытался:

template <class Type>
catch(Stack<Type>::Range) { }

Error: Expected 'catch' before '<' token       (What Wrong)


template<class Type>
try { //Code }
catch(Stack<Type>::Range) { }

Error: A template declaration cannot appear at block scope  (Definetely Wrong, I Know)

template<class Type>
int main()
{
    try
    {
        //Code
    }
    catch(Stack<Type>::Range) { }
}

Error: Cannot declare '::main' to be a template   (Of course, That totally wrong.)

Я пытался объявить "Тип" во многих местах, хотя я знал, что это неправильно. Если я не объявляю "Тип", это тоже неправильно. Итак, можно ли мне это сделать?

заранее спасибо

Теги:
templates
exception
types

2 ответа

2
Лучший ответ

Если у меня есть такая проблема (которую я бы хотел избежать в первую очередь, изменив весь код кода), я мог бы попытаться сделать что-то вроде этого:

template<typename E>
void TryAndCatch(
    std::function<void (void)> tried,
    std::function<void (const E&) catched>
) {
    try {
        tried();
    } catch (const E& exception) {
        catched(exception);
    }
}

и затем используйте его следующим образом:

TryAndCatch<Stack<int>::Range>(
    []() {
        // tried code in lambda expression
    },
    [](const Stack<int>::Range& exception) {
        // catch code
    }
);

Но просто взглянув на это, я настоятельно рекомендовал бы переписать код, чтобы мне не нужно было его использовать, например, например, @Spook.

Обратите внимание, что шаблон должен быть создан таким образом, чтобы либо вы выбрали исключение, которое вы ловите, а затем используете шаблоны, чтобы каким-то образом помочь вам (возможно, обернуть код в каком-либо классе шаблонов, который будет обрабатывать их?) Или обеспечить некоторый общий знаменатель - интерфейс, абстрактную базу класс, ваш выбор.

  • 0
    Ну, это слишком сложно, но это единственное решение моей проблемы ... Причина, по которой я определил исключения как подклассы, заключается в том, что я научился ловить исключения в этом качестве. Спасибо
  • 0
    Может быть, вы должны попытаться создать какую-нибудь оболочку / обработчик, который бы обрабатывал только исключения? Сделали это шаблоном класса, с типом исключения и функцией catch в качестве параметров, и просто заставили его косвенно обрабатывать ваш код?
Показать ещё 1 комментарий
3

Как правило, я не уверен, что определение исключений в качестве подклассов - хорошая идея. По крайней мере, я не видел этого в любой более крупной структуре (VCL,.NET, stl, но это не значит, конечно, нет).

У меня нет прямого решения вашей проблемы, но если никто не приходит с лучшим решением, вы всегда можете создать базовый класс для всех исключений Range и уловить их базовым классом, а не производными. Если вам нужна функциональность, специфичная для какого-либо типа, вы всегда можете создать виртуальный метод в базовом классе, например:

class BaseRangeException
{
public:
    virtual void Display() = 0;
}

template<typename T> RangeException 
class RangeException : public BaseRangeException
{
public:
    void Display()
    {
        // Implement differently, depending on type of template
    }
}
  • 0
    На самом деле, это хороший и простой способ сделать это. Тем не менее, ваше решение намного лучше в этом случае, так как мне не нужно писать так много строк ... Я уверен, что разработчики C ++ предсказали, что и должно быть решение
  • 0
    Что ж, это моё общее решение проблемы с дженериками - создать неуниверсальный базовый класс. Но это не всегда решает проблему. Хотя я не совсем уверен, что вы можете перехватывать исключения в общем виде.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню