首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >派生streambuf或basic_ostringstream?

派生streambuf或basic_ostringstream?
EN

Stack Overflow用户
提问于 2010-03-17 15:42:10
回答 4查看 2.4K关注 0票数 2

我想派生一个字符串流,这样我就可以使用operator<<构造一条消息,然后抛出该消息。API将如下所示:

代码语言:javascript
复制
error("some text") << " more text " << 42 << std::endl;

这应该会做一个

代码语言:javascript
复制
throw "some text more text 42"

所以我所做的就是创建一个errorbuf (继承自streambuf),它重载了'overflow‘方法,然后创建了一个ostream(&errorbuf)。我在想,我是不是应该从basic_ostringstream或其他什么地方继承。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-03-17 18:05:00

我将在这里再次介绍我最喜欢的宏:

代码语言:javascript
复制
#define ATHROW( msg )                                               \
{                                                                   \
    std::ostringstream os;                                          \
    os << msg;                                                      \
    throw ALib::Exception( os.str(), __LINE__, __FILE__ );          \
}                                                                   \

使用中:

代码语言:javascript
复制
ATHROW( "Invalid value: " << x << " should be " << 42 );

exception类型来自我自己的库,但我想你已经明白了。这比派生自己的流类简单得多,并且避免了op<<()带来的很多麻烦。

票数 2
EN

Stack Overflow用户

发布于 2010-03-17 15:49:34

您可以通过执行以下操作来简化此过程:

代码语言:javascript
复制
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&捕获。

这之所以有效,是因为临时表达式一直存在到完整表达式的末尾。

票数 3
EN

Stack Overflow用户

发布于 2010-03-17 20:41:14

GMan的解决方案中缺少一些运算符。

代码语言:javascript
复制
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;
};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2460549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档