Ben*_*Ben 104 c++ exception-handling exception
这是我想要向异常添加一些信息时经常做的一个例子:
std::stringstream errMsg;
errMsg << "Could not load config file '" << configfile << "'";
throw std::exception(errMsg.str().c_str());
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?
Ker*_* SB 158
标准异常可以从以下构造std::string:
#include <stdexcept>
char const * configfile = "hardcode.cfg";
std::string const anotherfile = get_file();
throw std::runtime_error(std::string("Failed: ") + configfile);
throw std::runtime_error("Error: " + anotherfile);
Run Code Online (Sandbox Code Playgroud)
需要注意的是基类std::exception可以不被这样构成; 你必须使用一个具体的派生类.
Tor*_*ten 44
这是我的解决方案:
#include <stdexcept>
#include <sstream>
class Formatter
{
public:
Formatter() {}
~Formatter() {}
template <typename Type>
Formatter & operator << (const Type & value)
{
stream_ << value;
return *this;
}
std::string str() const { return stream_.str(); }
operator std::string () const { return stream_.str(); }
enum ConvertToString
{
to_str
};
std::string operator >> (ConvertToString) { return stream_.str(); }
private:
std::stringstream stream_;
Formatter(const Formatter &);
Formatter & operator = (Formatter &);
};
Run Code Online (Sandbox Code Playgroud)
例:
throw std::runtime_error(Formatter() << foo << 13 << ", bar" << myData); // implicitly cast to std::string
throw std::runtime_error(Formatter() << foo << 13 << ", bar" << myData >> Formatter::to_str); // explicitly cast to std::string
Run Code Online (Sandbox Code Playgroud)
Nee*_*asu 25
有不同的例外,例如runtime_error,range_error,overflow_error, logic_error,等等.你需要将字符串传递到它的构造,并且您可以连接任何你想你的消息.那只是一个字符串操作.
std::string errorMessage = std::string("Error: on file ")+fileName;
throw std::runtime_error(errorMessage);
Run Code Online (Sandbox Code Playgroud)
你也可以boost::format像这样使用:
throw std::runtime_error(boost::format("Error processing file %1") % fileName);
Run Code Online (Sandbox Code Playgroud)
Max*_*kin 16
以下类可能非常方便:
struct Error : std::exception
{
char text[1000];
Error(char const* fmt, ...) __attribute__((format(printf,2,3))) {
va_list ap;
va_start(ap, fmt);
vsnprintf(text, sizeof text, fmt, ap);
va_end(ap);
}
char const* what() const throw() { return text; }
};
Run Code Online (Sandbox Code Playgroud)
用法示例:
throw Error("Could not load config file '%s'", configfile.c_str());
Run Code Online (Sandbox Code Playgroud)
Shr*_*han 11
如果是C++ 14(operator ""s),请使用字符串文字运算符
using namespace std::string_literals;
throw std::exception("Could not load config file '"s + configfile + "'"s);
Run Code Online (Sandbox Code Playgroud)
或者在C++ 11中定义自己的if.例如
std::string operator ""_s(const char * str, std::size_t len) {
return std::string(str, str + len);
}
Run Code Online (Sandbox Code Playgroud)
您的throw语句将如下所示
throw std::exception("Could not load config file '"_s + configfile + "'"_s);
Run Code Online (Sandbox Code Playgroud)
看起来很干净.
也许是这个?
throw std::runtime_error(
(std::ostringstream()
<< "Could not load config file '"
<< configfile
<< "'"
).str()
);
Run Code Online (Sandbox Code Playgroud)
它创建一个临时 ostringstream,根据需要调用 << 运算符,然后将其括在圆括号中,并对计算结果(这是一个 ostringstream)调用 .str() 函数,以将临时 std::string 传递给构造函数运行时错误。
注意: ostringstream 和字符串是临时右值,因此在该行结束后将超出范围。异常对象的构造函数必须使用复制或(更好的)移动语义获取输入字符串。
附加:我不一定认为这种方法是“最佳实践”,但它确实有效并且可以在紧要关头使用。最大的问题之一是此方法需要堆分配,因此运算符 << 可能会抛出异常。你可能不希望这种情况发生;然而,如果你进入这种状态,你可能有更多的问题需要担心!
| 归档时间: |
|
| 查看次数: |
136172 次 |
| 最近记录: |