gpt4 book ai didi

c++ - std::error_code,my_error::check_block == my_error::validate && my_error::accept_block == my_error::validate

转载 作者:可可西里 更新时间:2023-11-01 17:38:23 26 4
gpt4 key购买 nike

我正在使用 std::error_code 并定义和注册了一堆错误(使用枚举类)。

我有一个非常通用的错误,现在称为 my_error::validate,但我想在我的库中提供更具体的版本。通常人们会想要使用:

if (ec == bc::error::validate)
// ...

但是有时他们可能希望看到与该 std::error_code 关联的特定错误或打印错误消息。

// ec.message() says "check_block() failed to do XYZ"
assert(ec == bc::error::check_block);

我希望能够启用如下功能:

if (ec == bc::error::validate)
{
if (ec == bc::error::check_block)
// bc::error::check_block is a more specific case of bc::error::validate
}

似乎我可以以某种方式使用类别或条件?我怎样才能做到这一点而不需要定义一大堆新的错误枚举?它用于库,因此对于该库的用户来说,必须使用 bc::generic_error::validate 和 bc::error::check_block 会很痛苦。

代码如下:

#include <system_error>

namespace bc {

enum class error
{
// storage errors
missing_object = 1,
object_already_exists,
unspent_output,
// transaction_pool errors
bad_transaction,
// network errors
resolve_failed,
network_unreachable,
address_in_use,
listen_failed,
accept_failed,
bad_stream,
channel_stopped,
channel_timeout,
// validate
validate_failed,
check_block,
accept_block,
connect_block
};

class error_category_impl
: public std::error_category
{
public:
virtual const char* name() const;
virtual std::string message(int ev) const;
virtual std::error_condition default_error_condition(int ev) const;
};

const std::error_category& error_category();

std::error_code make_error_code(error e);
std::error_condition make_error_condition(error e);

} // bc

namespace std
{
template <>
struct is_error_code_enum<libbitcoin::error>
: public true_type {};
}

和 TU 源文件:

#include <bc/error.hpp>

namespace bc {

const char* error_category_impl::name() const
{
return "bitcoin";
}

std::string error_category_impl::message(int ev) const
{
error ec = static_cast<error>(ev);
switch (ec)
{
case error::missing_object:
return "Object does not exist";
case error::object_already_exists:
return "Matching previous object found";
case error::unspent_output:
return "Unspent output";
case error::bad_transaction:
return "Transaction failed to validate";
case error::resolve_failed:
return "Resolving hostname failed";
case error::network_unreachable:
return "Unable to reach remote network";
case error::address_in_use:
return "Address already in use";
case error::listen_failed:
return "Listen incoming connections failed";
case error::accept_failed:
return "Accept connection failed";
case error::bad_stream:
return "Bad stream";
case error::channel_stopped:
return "Channel stopped";
case error::channel_timeout:
return "Channel timed out";
default:
return "Unknown error";
}
}

std::error_condition
error_category_impl::default_error_condition(int ev) const
{
error ec = static_cast<error>(ev);
switch (ec)
{
case error::check_block:
case error::accept_block:
case error::connect_block:
//return error::validate_failed;
return std::errc::permission_denied;
default:
return std::error_condition(ev, *this);
}
}

const std::error_category& error_category()
{
static error_category_impl instance;
return instance;
}

std::error_code make_error_code(error e)
{
return std::error_code(static_cast<int>(e), error_category());
}

std::error_condition make_error_condition(error e)
{
return std::error_condition(static_cast<int>(e), error_category());
}

} // bc

最佳答案

好的,我从 boost::asio 和 std::error_code 的创建者和大师本人那里得到了帮助:Chris Kohlhoff。

使用 ADL 时,一个好的经验法则是它不需要任何限定符(在我的例子中是 error::error_code_t),而且我在错误的范围内。

#include <iostream>
#include <system_error>

namespace libbitcoin {

namespace error
{
// Specific errors
enum error_code_t
{
// storage errors
missing_object = 1,
object_already_exists,
unspent_output,
// transaction_pool errors
bad_transaction,
// network errors
resolve_failed,
network_unreachable,
address_in_use,
listen_failed,
accept_failed,
bad_stream,
channel_stopped,
channel_timeout,
// validate
check_block,
accept_block,
connect_block
};

// error_condition
enum error_condition_t
{
// validate
validate_failed = 1
};

std::error_code make_error_code(error_code_t e);
std::error_condition make_error_condition(error_condition_t e);
}

class error_category_impl
: public std::error_category
{
public:
virtual const char* name() const;
virtual std::string message(int ev) const;
virtual std::error_condition default_error_condition(int ev) const;
};

const std::error_category& error_category();

} // libbitcoin

namespace std
{
template <>
struct is_error_code_enum<libbitcoin::error::error_code_t>
: public true_type {};

template <>
struct is_error_condition_enum<libbitcoin::error::error_condition_t>
: public true_type {};
}

// -------------------------------------------------------------------

namespace libbitcoin {

namespace error {
std::error_code make_error_code(error_code_t e)
{
return std::error_code(static_cast<int>(e), error_category());
}

std::error_condition make_error_condition(error_condition_t e)
{
return std::error_condition(static_cast<int>(e), error_category());
}
}

const char* error_category_impl::name() const
{
return "bitcoin";
}

std::string error_category_impl::message(int ev) const
{
//error ec = static_cast<error>(ev);
switch (ev)
{
case error::missing_object:
return "Object does not exist";
case error::object_already_exists:
return "Matching previous object found";
case error::unspent_output:
return "Unspent output";
case error::bad_transaction:
return "Transaction failed to validate";
case error::resolve_failed:
return "Resolving hostname failed";
case error::network_unreachable:
return "Unable to reach remote network";
case error::address_in_use:
return "Address already in use";
case error::listen_failed:
return "Listen incoming connections failed";
case error::accept_failed:
return "Accept connection failed";
case error::bad_stream:
return "Bad stream";
case error::channel_stopped:
return "Channel stopped";
case error::channel_timeout:
return "Channel timed out";
case error::check_block:
return "Checkblk";
default:
return "Unknown error";
}
}

std::error_condition
error_category_impl::default_error_condition(int ev) const
{
//error ec = static_cast<error>(ev);
switch (ev)
{
case error::check_block:
case error::accept_block:
case error::connect_block:
return std::error_condition(error::validate_failed, *this);
default:
return std::error_condition(ev, *this);
}
}

const std::error_category& error_category()
{
static error_category_impl instance;
return instance;
}

} // libbitcoin

using namespace libbitcoin;

#include <assert.h>

int main()
{
std::error_code ec = error::check_block;
assert(ec == error::validate_failed);
assert(ec == error::check_block);
std::cout << ec.message() << std::endl;
//ec = error::missing_object;
return 0;
}

关于c++ - std::error_code,my_error::check_block == my_error::validate && my_error::accept_block == my_error::validate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9760851/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com