![](/img/trans.png)
[英]How can std::runtime_error::runtime_error(const std::string&) meet std::exception's requirement of throw()?
[英]Adding an extra string to std::runtime_error
我想要一个自定义异常,其中嵌入了上下文信息,包括字符串和格式化的what()
。
例如:
struct MyError : public std::runtime_error {
MyError(std::size_t line, std::size_t column, std::string expected, std::string found)
: std::runtime_error(FormatPrettyMessage(...)), line(line), column(column), expected(expected), found(found) {}
MyError(const MyError&) = default;
MyError& operator =(const MyError&) = default;
~MyError() = default;
size_t line;
size_t column;
std::string expected; // these are
std::string found; // problematic
};
但是, 最佳实践说异常应该有一个noexcept
复制构造函数,因为抛出可能涉及隐式复制。
上面不能有noexcept
复制构造函数,因为复制字符串会抛出std::badalloc
。 cppreference暗示标准库使用写时复制字符串来避免这种情况( libstdc++确实使用了内部 COW 字符串实现)。
但是外行人应该如何按照习惯将字符串成员添加到他们的自定义异常中呢? 尝试序列化我的数据并将其填充到runtime_error
消息中,正如这个答案所建议的那样,感觉很老套并强制异常处理代码解析和重新格式化what()
output。但是将整个自定义字符串扔到我的小项目中只是为了制作一个例外感觉很过分。
您可以移动字符串而不是复制它们,特别是因为您一开始就按值将它们传递给构造函数,所以在您的构造函数进入之前它们已经被调用者复制了。 std::string
移动构造函数被标记为noexcept
。
MyError(std::size_t line, std::size_t column, std::string expected, std::string found)
: std::runtime_error(FormatPrettyMessage(...)), line(line), column(column), expected(std::move(expected)), found(std::move(found)) {}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.