'make_error_code' 未在此范围内声明,并且在实例化时通过参数相关查找未找到任何声明
'make_error_code' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
我正在使用 boost::system::error_code
(来自 boost 1.62.0)在 C++ 中定义自定义错误代码,如下面的缩小示例所示:
#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
模板class的构造函数引用它之后声明的),但我怎么应该解决这个问题?
值得庆幸的是 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);
}
clang 在 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.
是的,参数依赖查找失败了,因为命名空间没有为 make_error_code
提供实现,因此您必须在模板实例化之前或在同一命名空间中移动它们。 是一个类似的问题,答案对此进行了更详细的解释。
这也适用于 gcc(在 is_error_code_enum
专门用于 boost::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);
}
我正在使用 boost::system::error_code
(来自 boost 1.62.0)在 C++ 中定义自定义错误代码,如下面的缩小示例所示:
#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
模板class的构造函数引用它之后声明的),但我怎么应该解决这个问题?
值得庆幸的是 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);
}
clang 在 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.
是的,参数依赖查找失败了,因为命名空间没有为 make_error_code
提供实现,因此您必须在模板实例化之前或在同一命名空间中移动它们。
这也适用于 gcc(在 is_error_code_enum
专门用于 boost::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);
}