<tfoot id='P9ZaU'></tfoot>

      <i id='P9ZaU'><tr id='P9ZaU'><dt id='P9ZaU'><q id='P9ZaU'><span id='P9ZaU'><b id='P9ZaU'><form id='P9ZaU'><ins id='P9ZaU'></ins><ul id='P9ZaU'></ul><sub id='P9ZaU'></sub></form><legend id='P9ZaU'></legend><bdo id='P9ZaU'><pre id='P9ZaU'><center id='P9ZaU'></center></pre></bdo></b><th id='P9ZaU'></th></span></q></dt></tr></i><div id='P9ZaU'><tfoot id='P9ZaU'></tfoot><dl id='P9ZaU'><fieldset id='P9ZaU'></fieldset></dl></div>
    1. <legend id='P9ZaU'><style id='P9ZaU'><dir id='P9ZaU'><q id='P9ZaU'></q></dir></style></legend>
        <bdo id='P9ZaU'></bdo><ul id='P9ZaU'></ul>

      <small id='P9ZaU'></small><noframes id='P9ZaU'>

      1. 如何确定输出流链是否结束?

        how to find out if output stream chain is ended?(如何确定输出流链是否结束?)
        1. <tfoot id='i90nu'></tfoot>

            <legend id='i90nu'><style id='i90nu'><dir id='i90nu'><q id='i90nu'></q></dir></style></legend>

              <tbody id='i90nu'></tbody>

              <bdo id='i90nu'></bdo><ul id='i90nu'></ul>
              • <small id='i90nu'></small><noframes id='i90nu'>

                  <i id='i90nu'><tr id='i90nu'><dt id='i90nu'><q id='i90nu'><span id='i90nu'><b id='i90nu'><form id='i90nu'><ins id='i90nu'></ins><ul id='i90nu'></ul><sub id='i90nu'></sub></form><legend id='i90nu'></legend><bdo id='i90nu'><pre id='i90nu'><center id='i90nu'></center></pre></bdo></b><th id='i90nu'></th></span></q></dt></tr></i><div id='i90nu'><tfoot id='i90nu'></tfoot><dl id='i90nu'><fieldset id='i90nu'></fieldset></dl></div>
                  本文介绍了如何确定输出流链是否结束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我想要达到什么目的?

                  如何确定流链是否结束?看看下面的函数(所有这些函数都在这个问题的 LogRouter 类中):

                  How can I find if a stream chain is ended? Look at the function below (all these functions are inside a LogRouter class in this question):

                  template<typename First, typename... Rest>
                  void log(const LogLevel &level_, First first_, Rest... rest_) {
                      sstream << first_ << " ";
                      log(level_, rest_...);
                  }
                  
                  void log(const LogLevel &level_) {
                      for(auto &route : routes)
                          route->stream() << sstream.str() << std::endl;
                  
                      sstream.clear();
                      sstream.str("");
                  }
                  

                  我想在上面实现完全相同的功能,但使用流.因此,当我到达流的末尾时,它需要将最终数据发送到路由,而不是使用

                  I want to achieve the exact same functionality in the above but using streams. So, when I reach an end of a stream it needs to send the final data to the routes and instead of using

                  router.log(LogLevel::Alert, "test stream", 15);
                  

                  我希望能够使用

                  router.log(LogLevel::Alert) << "test stream " << 15;
                  

                  我尝试过的:

                  • std::ostream 运算符重载不接受压缩变量.

                  • std::ostream operator overloading does not accept packed variables.

                  逐个遍历每个传递的值.如下图:

                  going through every single passed value one by one. Like below:

                   struct LogEnd {};
                  
                   static LogEnd end() { return LogEnd; }
                  
                   template<typename T> LogRouter &operator<<(const T &value) {
                       sstream << value;
                       return *this;
                   }
                  
                   LogRouter &log(const LogLevel &level_) {
                       currentLogLevel = level_; //had to add another variable
                       return *this;
                   }
                  
                   void operator<<(const LogEnd &end) {
                      for(auto &route : routes)
                          route.stream() << sstream.str() << std::endl;
                      currentLogLevel = LogLevel::None;
                  }
                  

                  这给了我我想要的语法明智,但我需要在每个结束时调用额外的 LogRouter::end():

                  This gives me what I want syntax wise but I need to call the additional LogRouter::end() at the end of every:

                   router.log(LogLevel::Alert) << "test stream " << 15 << LogRouter::end();
                  

                  我也有 std::endl 的语法,但如果我能在最后不加任何内容的情况下调用它,那将是最好的.

                  I have a syntax for std::endl also but it would be best if I can call it without anything in the end.

                  问题

                  有没有办法知道流链的末端.类似于使用递归可变参数模板函数时可以执行的操作.

                  Is there a way to know an end of a stream chain. Something similar to what you can do when using recursive variadic template function.

                  推荐答案

                  您可以将有趣的逻辑放入流的析构函数中.显然,我也会正确地处理流而不是制作一些看起来像流但实际上不是流的东西:

                  You could put the interesting logic into the stream's destructor. Obviously, I would also properly deal with stream rather than cooking up something which somewhat looks like a stream but isn't really a stream:

                  #include <iostream>
                  #include <sstream>
                  #include <string>
                  
                  class logstream
                      : private virtual std::stringbuf
                      , public std::ostream {
                      std::string level;
                  public:
                      logstream(std::string l)
                          : std::ostream(this)
                          , level(l) {
                      }
                      logstream(logstream&& other)
                      : std::stringbuf(std::move(other))
                      , std::ostream(std::move(other))
                      , level(std::move(other.level)) {
                          this->rdbuf(0);
                      }
                      ~logstream() {
                          std::cout << "do something interesting here("
                                    << this->level<< ", " << this->str() << ")
                  ";
                      }
                  };
                  
                  logstream trace() {
                      return logstream("trace");
                  }
                  
                  int main()
                  {
                      trace() << "hello, world";
                  }
                  

                  使用的流缓冲区(在本例中为std::stringbuf,但也可以是自定义流缓冲区)被创建为基类,以便在 std::ostream 之前构造它.原则上它是一个数据成员,但数据成员是在基类之后构造的.因此,它变成了一个 private 基类.

                  The stream buffer used (std::stringbuf in this case but it could also be a custom stream buffer) is made a base class to have it constructed before the std::ostream. In principle it is meant to be a data member but data members are constructed after the base classes. Thus, it is made a private base class instead.

                  事实证明 std::ostream 有一个 virtual 基类 (std::ios),这会导致 std::ostream 仍然在 std::stringbuf 之前构造,如果用于 std::stringbuf 的正常继承.使用 virtual 继承并使 std::stringbuf 成为第一个基类,确保它确实首先被构造.

                  It turns out that std::ostream has a virtual base class (std::ios) which would cause the std::ostream to still be constructed before the std::stringbuf if normal inheritance where used for std::stringbuf. Using virtual inheritance and making the std::stringbuf the first base class makes sure it really is constructed first.

                  这篇关于如何确定输出流链是否结束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Unable to access non-const member functions of objects in C++ std::set(无法访问 C++ std::set 中对象的非常量成员函数)
                  How should a size-limited stl-like container be implemented?(应该如何实现大小受限的 stl 类容器?)
                  Constructing std::function argument from lambda(从 lambda 构造 std::function 参数)
                  STL BigInt class implementation(STL BigInt 类实现)
                  Sync is unreliable using std::atomic and std::condition_variable(使用 std::atomic 和 std::condition_variable 同步不可靠)
                  Move list element to the end in STL(在 STL 中将列表元素移动到末尾)
                  <i id='mFDZt'><tr id='mFDZt'><dt id='mFDZt'><q id='mFDZt'><span id='mFDZt'><b id='mFDZt'><form id='mFDZt'><ins id='mFDZt'></ins><ul id='mFDZt'></ul><sub id='mFDZt'></sub></form><legend id='mFDZt'></legend><bdo id='mFDZt'><pre id='mFDZt'><center id='mFDZt'></center></pre></bdo></b><th id='mFDZt'></th></span></q></dt></tr></i><div id='mFDZt'><tfoot id='mFDZt'></tfoot><dl id='mFDZt'><fieldset id='mFDZt'></fieldset></dl></div>
                • <small id='mFDZt'></small><noframes id='mFDZt'>

                      <tbody id='mFDZt'></tbody>

                        1. <tfoot id='mFDZt'></tfoot>

                            <bdo id='mFDZt'></bdo><ul id='mFDZt'></ul>
                            <legend id='mFDZt'><style id='mFDZt'><dir id='mFDZt'><q id='mFDZt'></q></dir></style></legend>