Моя проблема в том, что у меня есть класс шаблона, и я пытаюсь поймать исключения из разных типов данных (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.)
Я пытался объявить "Тип" во многих местах, хотя я знал, что это неправильно. Если я не объявляю "Тип", это тоже неправильно. Итак, можно ли мне это сделать?
заранее спасибо
Если у меня есть такая проблема (которую я бы хотел избежать в первую очередь, изменив весь код кода), я мог бы попытаться сделать что-то вроде этого:
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.
Обратите внимание, что шаблон должен быть создан таким образом, чтобы либо вы выбрали исключение, которое вы ловите, а затем используете шаблоны, чтобы каким-то образом помочь вам (возможно, обернуть код в каком-либо классе шаблонов, который будет обрабатывать их?) Или обеспечить некоторый общий знаменатель - интерфейс, абстрактную базу класс, ваш выбор.
Как правило, я не уверен, что определение исключений в качестве подклассов - хорошая идея. По крайней мере, я не видел этого в любой более крупной структуре (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
}
}