是否可以捕获并打印初始化类对象的函数名称?我想要的是这样的:
class MyException: public std::exception
{
public:
MyException(const std::string message, const std::string caller = __func__)
: _caller(caller),
_msg(message)
{
...
}
std::string what(void); // prints messaged along with the caller
private:
...
}
在上面的类MyException
中,我希望调用者捕获实例化对象的函数名,以便警告用户抛出了哪个函数。我总能做到
...
throw MyException(message, __func__);
...
删除默认__func__
时。但是每当我实例化一个MyException
对象时,我就会做这个微不足道的事情。
有没有更好的方法来指导用户究竟抛出哪个函数?
提前致谢,
尼基尔
答案 0 :(得分:0)
如果我想为我的例外提供自动上下文,我可以这样做:
#include <iostream>
#include <stdexcept>
#include <string>
struct context_info {
explicit context_info(std::string function)
: _function { std::move(function) }
{}
// perhaps the context info will increase later to include class and instance?
friend std::string to_string(const context_info& ci)
{
return ci._function;
}
private:
std::string _function;
};
struct my_exception : std::runtime_error
{
my_exception(const std::string& message)
: std::runtime_error(message)
{}
my_exception(context_info context, const std::string& message)
: my_exception(message + " called from " + to_string(context))
{}
// everything else already taken care of for you
};
#if defined(NDEBUG)
#define THROW_WITH_CONTEXT(TYPE, ...) throw TYPE(__VA_ARGS__)
#else
#define THROW_WITH_CONTEXT(TYPE, ...) throw TYPE(context_info(__func__), __VA_ARGS__)
#endif
using namespace std;
void do_foo()
try {
THROW_WITH_CONTEXT(my_exception, "foo failure");
}
catch(const exception& e) {
cout << e.what() << endl;
}
int main() {
// your code goes here
try {
do_foo();
THROW_WITH_CONTEXT(my_exception, "error");
}
catch(const exception& e) {
cout << e.what() << endl;
}
return 0;
}
预期产出:
foo failure called from do_foo
error called from main
然而,整洁,因为它可能不是你应该做的,因为它不会在大型复杂程序中为你提供足够的上下文。
查看std::throw_with_nested
等文档。您可以在调用堆栈的每个阶段捕获异常,并使用其他上下文信息重新抛出异常。这更有用。