gpt4 book ai didi

c++ - 带有 std::error_code 的错误堆栈

转载 作者:太空狗 更新时间:2023-10-29 23:04:47 25 4
gpt4 key购买 nike

对于错误处理,异常对我来说是个问题,因为我的代码将是一个动态链接库。此外,我认为异常(exception)只应在特殊情况下使用。但是我会遇到可能发生错误的情况,这并非异常(exception)。另一个问题是我的库将从 C# 调用。因此,对所有错误使用异常似乎并不是正确的选择。

但我发现 std::error_code 和 std::error_category 的概念非常令人愉快,并且想在我的应用程序中使用它。但是,我也想提供某种错误堆栈跟踪。

考虑一个例子:用户想要从数据库中加载域对象。要加载此域对象,应用程序需要从不同的表中加载行。假设找不到所需的行之一。在这种情况下,数据库层会生成一些“未找到” 错误。如果我将此错误全部传播给用户,错误消息将不会很有帮助,因为没有人知道什么 没有找到。同样,如果每一层都处理下层的错误并生成相应的新错误,抽象出低级错误,我最终会得到类似“无法从数据库加载”的结果,这也不是很有帮助。我想要的是两者兼得。也就是说,每一层都会抽象出它从任何较低级别获得的错误,以便能够向最终用户显示描述性消息,但同时我不想丢失有关低级别错误的信息。所以我想要类似错误堆栈跟踪的东西。

我考虑过从 std::error_code 派生并使用指向底层 std::error_code 的指针和方法扩展类以获取所有这些底层对象。但是,我不确定这种技术是否是个好主意,因为我读到在设计 std::error_code 时要小心谨慎以使其高效。

We want error_code to be a value type that can be copied without slicing and without requiring heap allocation, but we also want it to have polymorphic behavior based on the error category.

编辑我现在认为这种技术也会引入切片问题,不是吗?

编辑 2我现在想通过派生自 std::error_code 来实现它。而不是指针,什么地方需要堆分配,我的派生类将有一个 boost::optional。这样内部错误代码可以简单地通过复制在堆栈上创建。一个不存在的内部错误代码可以用 boost::optional 正确表示。切片仍然是一个问题,但我想它可以忽略不计,因为将派生类的实例分配给 std::error_code 变量的情况是不必要的,即使它发生了,我也只会丢失有关内部错误代码的信息。此外,我可以提供从 std::error_code 到没有内部错误代码的派生类的转换。

编辑 3我没有想到不可能有一个包含 boost::optional 本身的类。所以现在我看不到在没有堆分配的情况下我想要的东西的任何可能性。

最佳答案

最后我从 std::error_code 派生。我的派生类有一个成员,它是指向同一类实例的指针。我向该类添加了一个 wrap() 方法,该方法采用同一类的实例作为参数,并在堆上分配它的一个拷贝。我的派生类的析构函数确保再次释放内存。我也为这个内部错误代码添加了一个 getter 方法。这样我可以堆叠几个错误代码。缺点是我需要堆分配,但我只是希望在我的场景中这不会导致严重的性能问题。我的类还提供从 std::error_code 的转换。


class my_error : public std::error_code
{
public:
my_error() : std::error_code(), m_innerError(NULL) {};
my_error( int val, const std::error_category & cat ) : std::error_code(val, cat), m_innerError(NULL) {};
my_error( std::error_code & error ) : std::error_code(error), m_innerError(NULL) {};
my_error( const std::error_code & error ) : std::error_code(error), m_innerError(NULL) {};
~my_error()
{
delete m_innerError;
}

template <class ErrorCodeEnum>
my_error(ErrorCodeEnum e,
typename boost::enable_if<std::is_error_code_enum<ErrorCodeEnum> >::type* = 0)
{
*this = make_custom_error(e);
}

template<typename ErrorCodeEnum>
typename boost::enable_if<std::is_error_code_enum<ErrorCodeEnum>, error_code>::type &
operator=( ErrorCodeEnum val )
{
*this = make_custom_error(val);
return *this;
}

my_error const * get_inner() const
{
return m_innerError;
};

void wrap( const my_error & error)
{
m_innerError = new my_error(error);
};

private:
my_error * m_innerError;
};

关于c++ - 带有 std::error_code 的错误堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21701628/

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