Search code examples
c++exceptiontry-catchnested-functioncatch-all

A single catch all statement for deeply nested functions in c++?


#include<bits/stdc++.h>
using namespace std;
void subtract(int a,int b){
    try{
        if(b==1)
            throw "Subtracting by 1 results in previous number";
            cout<<a-b<<endl;
    }
    catch(const char *e){
        cerr<<e<<endl;
    }
};
void add(int a,int b){
    try{
        if(b==1)
            throw "Adding with 1 results in next number";
    }
    catch(const char *e){
        cerr<<e<<endl;
        subtract(a+b,b);
    }
};
void multiply(int a,int b){
    try{
        if(b==1)
            throw "Multiplying with 1 has no effect!";
    }
    catch(const char *e){
        cerr<<e<<endl;
        add(a*b,b);
    }
};
void divide(int a,int b){
    try{
        if(b==1)
            throw "Dividing with one has no effect!";
    }
    catch(const char *e){
        cerr<<e<<endl;
        multiply(a/b,b);
    }
};
void bodmas(int a,int b){
    divide(a,b);
};
int main(){
    int a,b;
    cin>>a>>b;
    bodmas(a,b);
    return 0;
}

So I was trying to understand the concept of deeply nested functions as well as exception handling by writing a small program. But in this function I had to type catch statement seperately for each function. Is there any way to write a common catch all for all these functions maybe in main()? I am thinking suppose each function returns a different data type and a statement would be printed accordingly.


Solution

  • I am thinking suppose each function returns a different data type

    If you meant "would throw a different data type" then you can think about a template function that would do the printing job.

    template<typename T>
    void printException(T exept) {
         std::cerr << exept << std::endl;
    }
    

    To achieve something better (because one could pass by mistake something that std::cerr cannot print for many reasons), you could simply use std::exception and passing it a message when you construct your exception object so that when you catch it you could simply do:

    void printException(const std::exception& e)  {
        // print some information message if needed then...
        std::cerr << e.what() << std::endl;
    }
    

    Is there any way to write a common catch all for all these functions may be in main()?

    Yes, you simply have to remove all the catch statements in each of your functions and put one in main after a try block that would encompass all your 'risky methods' -- not that they are risky but that they can throw an exeption. Here's an example:

    int main(int argc, char** argv) {
        try {
            riskyMethod1();
            riskyMethod2();
            riskyMethod3();
        }
        catch (const std::exception& e) {
            printException(e);
        }
        return 0;
    }
    

    To achieve this, once again, I'd recommend dropping throwing strings to the benefit of exception objects. You could have dividing_with_one_exeption, multiplying_with_one_exception just to name a few (this is a suggestion since you can easily use std::exception, giving it your exception message).