C ++,捕获不同类型数据的异常

时间:2014-01-03 12:33:24

标签: c++ templates exception types

我的问题是我有一个模板类,我试图捕获不同类型数据的异常(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's 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's totally wrong.)

我试图在许多地方宣布'类型',即使我知道这是错的。如果我不宣布'类型',那也是错误的。那么,有什么方法可以做到吗?

提前致谢

2 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分: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建议的那样。

请注意,模板需要实例化,以便您选择要捕获的异常,然后使用模板以某种方式帮助您(可能将代码包装在一些模板类中以处理它们?)或确保一些共同点 - 接口,抽象基类,你的选择。

相关问题