Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom C++ exceptions with template arguments

I'm trying to learn how to use custom C++ exceptions with template arguments. This is a dummy program that I'm trying to compile unsuccessfully:

#include <string>
#include <iostream>

template <class T>
class MyException : public std::exception {
    public:
        T error;
        MyException(T err) { error = err; };
};


int main(void) {
    try {
        std::string err = "String error";
        throw MyException<std::string>(err);
        return 0;
    }
    catch (MyException e) {
        std::cout << e << std::endl;
        return 1;
    };
}

This is the error I get:

<source>: In function 'int main()':
<source>:18:9: error: invalid use of template-name 'MyException' without an argument list
   18 |  catch (MyException e) {
      |         ^~~~~~~~~~~
<source>:18:9: note: class template argument deduction is only available with '-std=c++17' or '-std=gnu++17'
<source>:5:7: note: 'template<class T> class MyException' declared here
    5 | class MyException : public std::exception {
      |       ^~~~~~~~~~~
<source>:19:22: error: 'e' was not declared in this scope
   19 |         std::cout << e << std::endl;
      |                      ^

Could you please help me to fix it for C++11?

like image 585
Medical physicist Avatar asked Feb 21 '26 13:02

Medical physicist


1 Answers

You can't catch any template! You can catch only specific type so only specific instance of template. So your code should look like this (quick fix):

#include <string>
#include <iostream>

template <class T>
class MyException : public std::exception {
    public:
        T error;
        MyException(T err) { error = err; };
};


int main(void) {
    try {
        std::string err = "String error";
        throw MyException<std::string>(err);
        return 0;
    }
    catch (const MyException<std::string>& e) {
        std::cout << e.what() << std::endl;
        return 1;
    };
}

https://godbolt.org/z/P4czdP

If you need some way to catch all exceptions for this template, you need extra layer of inheritance to introduce common unique parent type for this template:

#include <string>
#include <iostream>


class MyCommonException : public std::exception
{};

template <class T>
class MyException : public MyCommonException {
    public:
        T error;
        MyException(T err) { error = err; };
};


int main(void) {
    try {
        std::string err = "String error";
        throw MyException<std::string>(err);
        return 0;
    }
    catch (const MyCommonException& e) {
        std::cout << e.what() << std::endl;
        return 1;
    };
}

https://godbolt.org/z/xz8r5a

like image 84
Marek R Avatar answered Feb 24 '26 04:02

Marek R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!