2016-09-29 2 views
0

boost::system::error_code(ブースト1.62.0)を使用して、C++でカスタムエラーコードを定義しています細分化された例:'make_error_code'はこのスコープで宣言されておらず、インスタンス化の時点で引数依存ルックアップによって宣言が見つかりません

#include <boost/system/error_code.hpp> 
#include <boost/system/system_error.hpp> 

namespace mynamespace { 

enum class MyErrorCodeEnum : int { 
    ERROR1 = 1, 
    ERROR2 = 2, 
}; 


class MyErrorCategory: public boost::system::error_category 
{ 
public: 
    static const MyErrorCategory& instance() { 
     static MyErrorCategory category; 
     return category; 
    } 

    // error_category interface 
public: 
    virtual const char* name() const noexcept { 
     return "MyErrorCategory"; 
    } 
    virtual std::string message(int ev) const { 
     return "dummy"; 
    } 
}; 

} 

namespace boost { 
namespace system { 

inline error_code make_error_code(const mynamespace::MyErrorCodeEnum e) { 
    return error_code(static_cast<int>(e), mynamespace::MyErrorCategory::instance()); 
} 

inline error_condition make_error_condition(const mynamespace::MyErrorCodeEnum e) { 
    return error_condition(static_cast<int>(e), mynamespace::MyErrorCategory::instance()); 
} 

template<> 
struct is_error_code_enum<mynamespace::MyErrorCodeEnum>: public std::true_type {}; 

} 
} 


int main(int argc, char *argv[]) 
{ 
    throw boost::system::error_code(mynamespace::MyErrorCodeEnum::ERROR1); 
} 

これはMSVCを使ってうまくいきました。しかし、mingwの5.3.0に移動しようとすると、次のエラーがコンパイラによって報告された:それは報告されている理由

boost/system/error_code.hpp: In instantiation of 'boost::system::error_code::error_code(ErrorCodeEnum, typename boost::enable_if<boost::system::is_error_code_enum<ErrorCodeEnum> >::type*) [with ErrorCodeEnum = mynamespace::MyErrorCodeEnum; typename boost::enable_if<boost::system::is_error_code_enum<ErrorCodeEnum> >::type = void]': 
main.cpp:52:70: required from here 
boost/system/error_code.hpp:329:32: error: 'make_error_code' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] 
     *this = make_error_code(e); 
           ^
main.cpp:35:19: note: 'boost::system::error_code boost::system::make_error_code(mynamespace::MyErrorCodeEnum)' declared here, later in the translation unit 
inline error_code make_error_code(const mynamespace::MyErrorCodeEnum e) { 
       ^

私が見ることができる、それがのコンストラクタによって参照された後(make_error_code関数が宣言されていますerror_codeテンプレートクラス)、どうすればこの問題を解決できますか?ありがたいことに

+0

注釈:実際のコードは、直接ERROR_CODEではなく、それを中心に構築SYSTEM_ERRORをスローしないでしょう。しかし、それでも問題は変わりません。 – DevCybran

+0

'Make_error_code'宣言をクラス' MyErrorCategory'の前に置いてください。 –

+0

これは何も変わりません。 – DevCybran

答えて

2

coliruのエラーメッセージは、ここでは、より説明した作業バージョンです:

In file included from main.cpp:1: 
/usr/local/include/boost/system/error_code.hpp:329:17: error: call to function 'make_error_code' that is neither visible in the template definition nor found by argument-dependent lookup 
     *this = make_error_code(e); 
       ^
main.cpp:52:11: note: in instantiation of function template specialization 'boost::system::error_code::error_code<mynamespace::MyErrorCodeEnum>' requested here 
    throw boost::system::error_code(mynamespace::MyErrorCodeEnum::ERROR1); 
     ^
main.cpp:35:19: note: 'make_error_code' should be declared prior to the call site or in namespace 'mynamespace' 
inline error_code make_error_code(const mynamespace::MyErrorCodeEnum e) { 
       ^
1 error generated. 

そうそう、引数依存ルック:coliruより広範に打ち鳴らすによって生成

#include <boost/system/error_code.hpp> 
#include <boost/system/system_error.hpp> 

namespace mynamespace { 

enum class MyErrorCodeEnum : int { 
    ERROR1 = 1, 
    ERROR2 = 2, 
}; 


class MyErrorCategory: public boost::system::error_category 
{ 
public: 
    static const MyErrorCategory& instance() { 
     static MyErrorCategory category; 
     return category; 
    } 

    // error_category interface 
public: 
    virtual const char* name() const noexcept { 
     return "MyErrorCategory"; 
    } 
    virtual std::string message(int ev) const { 
     return "dummy"; 
    } 
}; 


inline boost::system::error_code make_error_code(const MyErrorCodeEnum e) { 
    return boost::system::error_code(static_cast<int>(e), MyErrorCategory::instance()); 
} 

inline boost::system::error_condition make_error_condition(const MyErrorCodeEnum e) { 
    return boost::system::error_condition(static_cast<int>(e), MyErrorCategory::instance()); 
} 

} 

template<> 
struct boost::system::is_error_code_enum<mynamespace::MyErrorCodeEnum>: public std::true_type {}; 


int main(int argc, char *argv[]) 
{ 
    throw boost::system::error_code(mynamespace::MyErrorCodeEnum::ERROR1); 
} 

メッセージ名前空間がmake_error_codeの実装を提供していなかったので、テンプレートインスタンス化の前に、または同じ名前空間に移動する必要があったためです。 Hereはこれと同様の質問ですが、答えがこれを詳しく説明しています。

これは、同様に、GCCの作品(場合にis_error_code_enumboost::systemの内側に特化しています):

#include <boost/system/error_code.hpp> 
#include <boost/system/system_error.hpp> 

namespace mynamespace { 

enum class MyErrorCodeEnum : int { 
    ERROR1 = 1, 
    ERROR2 = 2, 
}; 

} 

namespace boost { 
namespace system { 

template<> 
struct is_error_code_enum<mynamespace::MyErrorCodeEnum>: public std::true_type {}; 

} 
} 

namespace mynamespace { 

class MyErrorCategory: public boost::system::error_category 
{ 
public: 
    static const MyErrorCategory& instance() { 
     static MyErrorCategory category; 
     return category; 
    } 

    // error_category interface 
public: 
    virtual const char* name() const noexcept { 
     return "MyErrorCategory"; 
    } 
    virtual std::string message(int ev) const { 
     return "dummy"; 
    } 
}; 


inline boost::system::error_code make_error_code(const MyErrorCodeEnum e) { 
    return boost::system::error_code(static_cast<int>(e), MyErrorCategory::instance()); 
} 

inline boost::system::error_condition make_error_condition(const MyErrorCodeEnum e) { 
    return boost::system::error_condition(static_cast<int>(e), MyErrorCategory::instance()); 
} 

} 

int main(int argc, char *argv[]) 
{ 
    throw boost::system::error_code(mynamespace::MyErrorCodeEnum::ERROR1); 
} 
+0

私のコンパイラ設定では、異なる名前空間の 'is_error_code_enum'の特殊化について不平を言ってエラーが出るので、boost :: system名前空間に戻さなければなりませんでした。それとは別に、それは素晴らしい仕事です!私がmynamespaceにメソッドを移動することがなぜ助けになるのか分かりませんが、なぜコンパイラは 'error_code'テンプレート評価の間にそれらを参照していますか? – DevCybran

+0

@DevCybran - リンクされた質問を参照し、2番目の回答は検索の仕組みを説明します。専門分野に関して正確なエラーは何ですか? –

+0

説明をありがとう! 正確なエラーは次のとおりです: 'main.cpp:42:23:error:テンプレート ' struct boost :: system :: is_error_code_enum'の異なる名前空間での特殊化[-fpermissive]' – DevCybran

関連する問題