我的问题是我有一个模板类,我试图捕获不同类型数据的异常(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.)
我试图在许多地方宣布'类型',即使我知道这是错的。如果我不宣布'类型',那也是错误的。那么,有什么方法可以做到吗?
提前致谢
答案 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建议的那样。
请注意,模板需要实例化,以便您选择要捕获的异常,然后使用模板以某种方式帮助您(可能将代码包装在一些模板类中以处理它们?)或确保一些共同点 - 接口,抽象基类,你的选择。