派生流缓冲或basic_ostringstream?
-
20-09-2019 - |
题
欲导出字符串流,这样我可以使用操作员<<构建然后将被抛出的消息。该API将如下所示:
error("some text") << " more text " << 42 << std::endl;
此应该做一个
throw "some text more text 42"
因此,我所做的是使其中重载“溢出”的方法的errorbuf(从流缓冲继承),然后创建一个ostream(&errorbuf)。我不知道如果我不应该,而不是从basic_ostringstream或继承的东西...
解决方案
我要在这里再次小跑了我最喜欢的宏:
#define ATHROW( msg ) \
{ \
std::ostringstream os; \
os << msg; \
throw ALib::Exception( os.str(), __LINE__, __FILE__ ); \
} \
在使用:
ATHROW( "Invalid value: " << x << " should be " << 42 );
异常类型是从我自己的图书馆,但我认为你的想法。这比获得自己的流类简单得多,而且避免了很多讨厌的并发症与OP <<()。
其他提示
您也许可以更容易通过做这样的事情:
class error_builder
{
public:
error_builder(const std::string& pMsg = "")
{
mMsg << pMsg;
}
~error_builder(void)
{
throw std::runtime_error(mMsg.str());
}
template <typename T>
error_builder& operator<<(const T& pX)
{
mMsg << pX;
return *this;
}
private:
std::stringstream mMsg;
};
error_builder("some text") << " more text " << 42 << std::endl;
请注意,你不应该抛出字符串像你这样,所以我用std::runtime_error
。所有的异常应该从std::exception
,这runtime_error
做得出,这样,所有有意义的异常可以用常量std::exception&
抓住了。
此工作,因为该临时生活直至充分表达的末尾。
一些运营商从GMAN的溶液丢失。
class error {
public:
explicit error(const std::string& m = "") :
msg(m, std::ios_base::out | std::ios_base::ate)
{}
~error() {
if(!std::uncaught_exception()) {
throw std::runtime_error(msg.str());
}
}
template<typename T>
error& operator<<(const T& t) {
msg << t;
return *this;
}
error& operator<<(std::ostream& (*t)(std::ostream&)) {
msg << t;
return *this;
}
error& operator<<(std::ios& (*t)(std::ios&)) {
msg << t;
return *this;
}
error& operator<<(std::ios_base& (*t)(std::ios_base&)) {
msg << t;
return *this;
}
private:
std::ostringstream msg;
};
我通常只是创建自己的异常类。你只需要覆盖what()
并且只要你喜欢可以提供尽可能多的构造。建立起来的错误消息,只需使用vasprintf(如果可用)或std :: ostringstream像上面。
下面是一个例子:
class CustomException : public std::exception {
private:
const std::string message;
public:
CustomException(const std::string &format, ...) {
va_list args;
va_start(args, format);
char *formatted = 0;
int len = vasprintf(&formatted, format.c_str(), args);
if (len != -1) {
message = std::string(formatted);
free(formatted);
} else {
message = format;
}
va_end(args);
}
const char *what() const {
return message.c_str();
}
};
如果你没有vasprintf,你也可以在栈上使用vsnprintf带缓冲...
不隶属于 StackOverflow