简体   繁体   English

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

[英]C++, Catching exceptions of different types of data

My problem is that I have a template class and i try to catch exceptions of different types of data (int, float, long, char etc). 我的问题是我有一个模板类,我尝试捕获不同类型的数据(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;
} 

How could I do the same in 3 lines? 我该如何在3行中做同样的事情? I have tried: 我努力了:

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.)

I have tried to declare 'Type' in many places, even though i knew it was wrong. 我已经尝试在很多地方声明“类型”,即使我知道这是错误的。 If i don't declare 'Type' it is also wrong. 如果我不声明“类型”,那也是错误的。 So, is there any way I could do it? 那么,有什么办法可以做到吗?

Thanks in advance 提前致谢

Generally, I'm not really sure if defining exceptions as subclasses is a good idea. 通常,我不确定将异常定义为子类是否是一个好主意。 At least I haven't seen that in any bigger framework (VCL, .NET, stl, but that does not mean, there are none, of course). 至少在更大的框架(VCL,.NET,stl)中,我还没有看到过,但这当然并不意味着没有。

I don't have a direct solution to your problem, but if noone comes with a better solution, you can always create a base class for all Range exceptions and catch them by the base class instead of derived ones. 我没有直接解决您的问题的方法,但是如果没有人提供更好的解决方案,则您始终可以为所有Range异常创建基类,并由基类(而不是派生类)捕获它们。 If you need a functionality specific to some type, you can always create a virtual method in the base class, like: 如果需要特定于某种类型的功能,则始终可以在基类中创建虚拟方法,例如:

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
    }
}

If I have such problem (which I'd like to avoid in the first place by changing the whole design of code) I might try to do something like this: 如果我遇到这样的问题(我想首先通过更改代码的整体设计来避免此问题),则可以尝试执行以下操作:

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

and then use it like this: 然后像这样使用它:

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

But just looking at it would made me strongly consider rewrite the code so that I would not need to use it, eg like @Spook suggested. 但是仅仅看一下它会使我强烈考虑重写代码,这样我就不需要使用它了,例如@Spook建议。

Notice that template needs to be instantiated so either you choose which exception you are catching, and then you use templates to help you somehow (maybe wrap code in some template class that would handle them?) or ensure some common denominator - interface, abstract base class, your choice. 请注意,模板需要实例化,因此您可以选择要捕获的异常,然后使用模板以某种方式帮助您(也许将代码包装在可以处理它们的某些模板类中?)或确保使用一些通用的分母-接口,抽象基上课,您的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM