10

C ++ 11system_errorエラーコードライブラリを使用して、作成しているライブラリのカスタムエラークラスを作成しています。以前にでこれを行っboost::error_codeたことがありますが、で動作させることはできませんstd::error_code。GCC4.6を使用しています。

基本的に、エラークラス、error_category、およびカスタム列挙型をstd::error_codeオブジェクトに変換するための変換ルーチンをSTD名前空間に作成するためのすべての定型コードをレイアウトしました。

namespace mylib
{
    namespace errc {

        enum my_error
        {
            failed = 0
        };

        inline const char* error_message(int c)
        {
            static const char* err_msg[] = 
            {
                "Failed",
            };

            assert(c < sizeof(err_msg) / sizeof(err_msg[0]));
            return err_msg[c];
        }

        class my_error_category : public std::error_category
        {
            public:

            my_error_category()
            { }

            std::string message(int c) const
            { 
                return error_message(c); 
            }

            const char* name() const { return "My Error Category"; }

            const static error_category& get()
            {
                const static my_error_category category_const;
                return category_const;
            }
        };

    } // end namespace errc
} // end namespace mylib

namespace std {

inline error_code make_error_code(mylib::errc::my_error e)
{
    return error_code(static_cast<int>(e), mylib::errc::my_error_category::get());
}

template<>
struct is_error_code_enum<mylib::errc::my_error>
    : std::true_type
{ }; 


問題は、エラーコードの列挙型とstd::error_codeオブジェクト間の暗黙的な変換が機能していないように見えるため、たとえば、のインスタンスstd::error_codeを列挙型リテラルと比較することはできません。

int main()
{
    std::error_code ec1 = std::make_error_code(mylib::errc::failed); // works
    std::error_code ec2 = mylib::errc::failed; // doesn't compile
    bool result = (ec2 == mylib::errc::failed); // doesn't compile
}

ec2 == mylib::errc::failedはコンパイルされません-私は言わなければなりませんec2 == std::make_error_code(mylib::errc::failed)

コンパイラが発行するエラーは次のとおりです。

In file included from test6.cc:3:0:
/usr/include/c++/4.6/system_error: In constructor ‘std::error_code::error_code(_ErrorCodeEnum, typename std::enable_if<std::is_error_code_enum<_ErrorCodeEnum>::value>::type*) [with _ErrorCodeEnum = mylib::errc::my_error, typename std::enable_if<std::is_error_code_enum<_ErrorCodeEnum>::value>::type = void]’:
test6.cc:70:37:   instantiated from here
/usr/include/c++/4.6/system_error:127:9: error: cannot convert ‘mylib::errc::my_error’ to ‘std::errc’ for argument ‘1’ to ‘std::error_code std::make_error_code(std::errc)’

そして、ここにIdeoneリンクがあります。

では、なぜこれが機能しないのですか?mylib::errc::my_error列挙型を暗黙的に変換できるようにするには、追加の定型コードが必要std::error_codeですか?の専門化std::make_error_codeがそれをやってくれると思いましたか?

4

1 に答える 1

9

error_code make_error_code(mylib::errc::my_error e)関数をからstdエラー名前空間( )に移動する必要がありますmylib::errchttp://ideone.com/eSfeeを確認してください。

于 2012-08-15T19:09:09.313 に答える