我想派生一个字符串流,这样我就可以使用operator<<构造一条消息,然后抛出该消息。API将如下所示:
error("some text") << " more text " << 42 << std::endl;这应该会做一个
throw "some text more text 42"所以我所做的就是创建一个errorbuf (继承自streambuf),它重载了'overflow‘方法,然后创建了一个ostream(&errorbuf)。我在想,我是不是应该从basic_ostringstream或其他什么地方继承。
发布于 2010-03-17 18:05:00
我将在这里再次介绍我最喜欢的宏:
#define ATHROW( msg ) \
{ \
std::ostringstream os; \
os << msg; \
throw ALib::Exception( os.str(), __LINE__, __FILE__ ); \
} \使用中:
ATHROW( "Invalid value: " << x << " should be " << 42 );exception类型来自我自己的库,但我想你已经明白了。这比派生自己的流类简单得多,并且避免了op<<()带来的很多麻烦。
发布于 2010-03-17 15:49:34
您可以通过执行以下操作来简化此过程:
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就是这样做的,这样所有有意义的异常都可以用const std::exception&捕获。
这之所以有效,是因为临时表达式一直存在到完整表达式的末尾。
发布于 2010-03-17 20:41:14
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;
};https://stackoverflow.com/questions/2460549
复制相似问题