Unimportant
Unimportant

Reputation: 2096

Avoiding macros for near identical class definitions

I have a base class for exceptions:

class BaseException : public std::runtime_error
{
public:

    BaseException(int Code, std::string Msg) : runtime_error(Msg);

    //...etc
};

In every class that needs exceptions, I embed a Exception class that inherits from BaseException:

class Foo
{
public:

    class Exception : public BaseException
    {
    public:

        Exception(int Code, std::string OptMsg = "") : BaseException(Code, OptMsg);

        enum
        {
            Fire,
            Flood,
            Aliens
        };
    };

    //...etc
};

So now I can throw(Exception::Fire) inside Foo and catch by base class or by Foo::Exception& and compare to Foo::Exception::Fire for example.

The Exception class definition is nearly identical every time tough, only the enum contents change. Because of DRY, I was thinking of writing a macro that allows something like this:

EXCEPTIONS
Fire,
Flood,
Aliens
END_EXCEPTIONS

However, macro's are frowned upon in C++. Is there a better way?

Upvotes: 2

Views: 92

Answers (2)

How about:

template <typename T>
struct Exception : BaseException
{
     Exception(int Code, std::string OptMsg = "") : BaseException(Code, OptMsg);
};

class Foo
{
public:

    using Exception = ::Exception<Foo>;    
    enum ExceptionCodes
    {
        Fire,
        Flood,
        Aliens
    };

    //...etc
};

(above unseen by a compiler)

The only difference is that you have to refer to Foo::Fire or Foo::ExceptionCodes::Fire.

You could do without the using statement, and just refer to Exception<Foo>.

Upvotes: 2

Joseph Thomson
Joseph Thomson

Reputation: 10393

You can "inherit" the BaseException constructors with the using keyword instead of manually reimplementing them. This should save you some typing. The rest of the boilerplate is pretty minimal, so I personally wouldn't worry about it.

struct Foo {
  struct Exception : BaseException {
    using BaseException::BaseException;
    enum {
      Fire,
      Flood,
      Aliens
    };
  };
};

Upvotes: 2

Related Questions