Humanity

Edit the world by your favorite way

C++でこんなことしたい

こんな風にエラー用のクラスを生成したいんだけどできない。
何か根本的に間違ってるような気がしないでもない。
自分としてはvectorとかから継承できるんだからこれでもできるだろーとか思ったのに・・・

namespace error {
    using namespace std;

    template <const char* errmsg>
    struct make_error_class
        : public exception {

        virtual const char*
        what() const throw() {
            return errmsg;
        }
    };

    struct invalid_type
        : public make_error_class<"invalid type error"> {};

    struct undefined_value
        : public make_error_class<"undefined value error"> {};
}

エラーメッセージ

error.h:21: error: ‘"invalid type error"’ is not a valid template argument for type ‘const char*’ because string literals can never be used in this context
error.h:24: error: ‘"undefined value error"’ is not a valid template argument for type ‘const char*’ because string literals can never be used in this context

妥協案

とりあえずこのようにerror_baseを継承する形で例外クラスを追加していくことにした。
単にstd::exceptionから継承するよりは楽。

namespace error {
    using namespace std;

    struct error_base
        : public exception {
        const char *errmsg;

        error_base(const char* errmsg) {
            this->errmsg = errmsg;
        }

        virtual const char*
        what() const throw() {
            if (errmsg == NULL)
                return "";
            else
                return errmsg;
        }
    };

    struct invalid_type
        : public error_base {
        invalid_type() : error_base("invalid type error") {
        }
    };

    struct undefined_value
        : public error_base {
        undefined_value() : error_base("undefined value error") {
        }
    };
}