Короче говоря , проблема заключается в разрешении имени.
Объяснение: Я перечисляю коды ошибок и использую их для получения / реализации класса std::error_condition
, однакоСуществует проблема при переносе реализации в 2 отдельных пространства имен, одно для перечислений и другое для реализации кода.
Это нелегко объяснить, поэтому я создал минимально компилируемый код, который вы можете просто скопировать / вставить в редактор и попробоватьдля компиляции.
Я поместил (NOTE :) комментарий поверх кода, что я и делаю для компиляции кода, но мне нужны отдельные пространства имен, как показано в коде ниже, но разрешение имен нене работает, и я не знаю, как это исправить.
#include <string>
#include <system_error>
// *NOTE*: if we rename this from 'enums' to 'app' (comment below) and do
// the needed name change changes in the code it will compile just fine
//namespace app
namespace enums
{
// error type enum
enum class Error
{
SignalFail, // failed to set up or execute signal
BadArgument, // bad argument passed to function
InvalidPointer, // Pointer is invalid
NoImplementation, // No implementation
OutOfRange, // Out of range
AlocationFailed, // Failed to alocate memory
MemoryReadFailed, // Failed to read memory
Unexpected // Unexpected execution flow
};
// error condition enum
enum class Condition
{
code_error,
unknown_error
};
}
// Register Error and Condition as error enum and condition enum
namespace std
{
template<>
struct is_error_code_enum<enums::Error> :
public true_type {};
template<>
struct is_error_condition_enum<enums::Condition> :
public true_type {};
}
namespace app
{
// Category types are used to identify the source of an error.
// They also define the relation between error_code and error_condition objects of its category,
// as well as the message set for error_code objects.
class error_category_t :
public std::error_category
{
public:
error_category_t() noexcept {};
inline const char* name() const noexcept override;
std::error_condition default_error_condition(int err_value) const noexcept override;
inline bool equivalent(const std::error_code& err_code, int err_value) const noexcept override;
inline bool equivalent(int err_value, const std::error_condition& err_cond) const noexcept override;
std::string message(int ev) const override;
private:
error_category_t(const error_category_t&) = delete;
error_category_t(error_category_t&&) = delete;
error_category_t& operator=(const error_category_t&) = delete;
error_category_t& operator=(error_category_t&&) = delete;
} const error_category;
const char* error_category_t::name() const noexcept
{
return "app category";
}
bool error_category_t::equivalent(const std::error_code& err_code, int err_value) const noexcept
{
return *this == err_code.category() &&
static_cast<int>(default_error_condition(err_code.value()).value()) == err_value;
}
bool error_category_t::equivalent(int err_value, const std::error_condition& err_cond) const noexcept
{
return default_error_condition(err_value) == err_cond;
}
//
// make_error_condition overload to generate custom conditions:
// This function is called by error_condition's constructor for error condition enum types,
// and should be overloaded for all custom error condition enum types in order to
// provide a mechanism to generate the appropriate error_condition objects from them.
//
inline std::error_condition make_error_condition(enums::Condition ec) noexcept
{
return std::error_condition(static_cast<int>(ec), error_category);
}
//
// This function is called by error_code's constructor for error code enum types
//
inline std::error_code make_error_code(enums::Error code) noexcept
{
return std::error_code(static_cast<int>(code), error_category);
}
}
namespace app
{
std::error_condition error_category_t::default_error_condition(int err_value) const noexcept
{
switch (static_cast<enums::Error>(err_value))
{
case enums::Error::SignalFail:
case enums::Error::BadArgument:
case enums::Error::InvalidPointer:
case enums::Error::NoImplementation:
case enums::Error::OutOfRange:
case enums::Error::AlocationFailed:
case enums::Error::MemoryReadFailed:
case enums::Error::Unexpected:
return std::error_condition(enums::Condition::code_error);
default:
return std::error_condition(enums::Condition::unknown_error);
}
}
std::string error_category_t::message(int err_value) const
{
switch (static_cast<enums::Error>(err_value))
{
case enums::Error::SignalFail:
return "Signaling failed";
case enums::Error::BadArgument:
return "Bad Argument";
case enums::Error::InvalidPointer:
return "Invalid pointer";
case enums::Error::NoImplementation:
return "No implementation";
case enums::Error::OutOfRange:
return "Out of range";
case enums::Error::AlocationFailed:
return "Memory allocation failed";
case enums::Error::MemoryReadFailed:
return "Memory read failed";
case enums::Error::Unexpected:
return "Unexpected execution flow";
default:
return "Unknown error";
}
}
}