- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
对于错误处理,异常对我来说是个问题,因为我的代码将是一个动态链接库。此外,我认为异常(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/
出于好奇 - 我知道有 LAMP - Linux、Apache、MySQL 和 PHP。但是还有哪些其他 Web 堆栈替代方案的缩写呢?像 LAMR - Linux、Apache、MySQL Ruby
我有以下代码。 var stackMapIn = []; var stackMapOut = []; var stackBack = []; stackMapOut.push("m1"); $scop
我遇到了导致我的堆栈无法恢复的情况,我别无选择,只能将其删除。使用完全相同的模板,我继续创建了另一个同名的堆栈。 The following resource(s) failed to create:
这是我第一次查看 Node 堆栈,自从我学习使用 Ruby on Rails 进行 Web 开发以来,我对一些基本的东西有点困惑。我了解 Rails 目录是什么样的。 demo/ ..../app .
本文实例讲述了C语言使用深度优先搜索算法解决迷宫问题。分享给大家供大家参考,具体如下: 深度优先搜索 伪代码 (Pseudocode)如下: ?
我正在按照指南 here ,它告诉我: The stack setup will download the compiler if necessary in an isolatedlocation (
同时 trying to debug a different question ,我安装了一个似乎与我安装的其他一些软件包冲突的软件包。 我跑了 $ stack install regex-pcre-
我花了几个小时创建了一个方法,该方法将从堆栈 s1 中获取 null 元素,并将它们放入 s2 中。然后该类应该打印堆栈。方法如下 import net.datastructures.ArraySta
我有一个类Floor,它有一个Stack block ,但我不知道如何初始化它。我曾尝试过这样的: public class Floor { private Stack stack;
我知道这个问题已经问过很多次了,但搜索一个小时后我仍然遇到问题。 我想使用一个 lifo 堆栈,它可以存储最大数量的元素。达到最大数量后,首先删除该元素并将其替换为新元素,这样在第一次弹出时我可以获取
我需要编写一个方法,压缩以执行以下操作; 目标compress方法是从栈s1中移除所有null元素。剩余(非空)元素应按其初始顺序保留在 s1 上。辅助堆栈 s2 应用作s1 中元素的临时存储。在该方
我正在尝试验证以下代码发生的顺序。 function square(n) { return n * n; } setTimeout(function(){ console.log("H
我需要一个字符数组,其中包含基于特定文件夹中文件数量的动态数量的字符数组。我能够通过初始化 char (*FullPathNames)[MAX_FILENAME_AND_PATHNAME_LENGTH
我正在编写一些日志逻辑并想要进行一些缩进。了解是否存在任何函数调用或某个函数是否已完成的最简单方法是查看堆栈/帧的当前地址。让我们假设堆栈颠倒增长。然后,如果 log() 调用中的堆栈地址小于前一次调
所以内存分段在x86-64中被放弃了,但是当我们使用汇编时,我们可以在代码中指定.code和.data段/段,并且还有堆栈指针寄存器。 还有堆栈段、数据段和代码段寄存器。 代码/数据/堆栈的划分是如何
void main() { int x = 5; // stack-allocated Console.WriteLine(x); } 我知道 x 是堆栈分配的。但是关于 x 的堆栈中
这是我关于 SO 的第一个问题。这可能是一个愚蠢的问题,但到目前为止我还没弄明白。 考虑下面的程序 Reader.java: public class Reader { public
java中有没有一种快速的方法来获取嵌套/递归级别? 我正在编写一个函数来创建组及其成员的列表。成员也可以是团体。我们最终可能会得到一组循环的组/成员。 我想在某个任意级别停止。 我知道我可以将变量保
考虑以下代码: struct A{...}; A a[100]; A* pa = new A[100]; delete[] pa; a/pa 元素的销毁顺序是由标准定义的还是实现定义的(对于第二种情况
我在下面有一些代码。此代码是一个基本的压入/弹出堆栈类,我将其创建为模板以允许某人压入/弹出堆栈。我有一个家庭作业,我现在要做的是创建一个具有多个值的堆栈。 所以我希望能够创建一个基本上可以发送三个整
我是一名优秀的程序员,十分优秀!