如何确定输出流链是否已结束?
how to find out if output stream chain is ended?
我想实现什么?
如何找到流链是否已结束?看看下面的函数(在这个问题中,所有这些函数都在 LogRouter 类中):
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("");
}
我想在上面实现完全相同的功能,但使用流。因此,当我到达流的末尾时,它需要将最终数据发送到路由,而不是使用
router.log(LogLevel::Alert, "test stream", 15);
我希望能够使用
router.log(LogLevel::Alert) << "test stream " << 15;
我尝试过的:
std::ostream
运算符重载不接受打包变量。逐个检查每个传递的值。如下所示:
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()
:router.log(LogLevel::Alert) << "test stream " << 15 << LogRouter::end();
我也有一个
std::endl
语法,但最好是我可以在最后没有任何内容的情况下调用它。
问题
有没有办法知道流链的末端。类似于使用递归可变参数模板函数时可以执行的操作。
您可以将有趣的逻辑放入流的析构函数中。显然,我也会正确处理流,而不是制作一些看起来有点像溪流但实际上不是流的东西:
#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() << ")n";
}
};
logstream trace() {
return logstream("trace");
}
int main()
{
trace() << "hello, world";
}
使用的流缓冲区(在这种情况下std::stringbuf
,但它也可以是自定义流缓冲区)被设为基类,以便在std::ostream
之前构造它。原则上,它意味着数据成员,但数据成员是在基类之后构造的。因此,它被设为private
基类。
事实证明,std::ostream
有一个virtual
基类(std::ios
),如果用于std::stringbuf
的正常继承,这将导致std::ostream
仍然在std::stringbuf
之前构造。使用virtual
继承并将std::stringbuf
作为第一个基类可确保它确实首先构造。
相关文章:
- 在函数结束后使用指向变量的指针是否安全?
- 数组对象的生存期是否在重用其元素存储时结束?
- 在不释放所有动态分配的资源的情况下结束程序是否有风险
- 在新作用域中使用unique_lock是否等效于在使用共享资源的工作结束时解锁调用
- 是否可以在基于范围的 for 循环中使用模板化的开始/结束方法
- 如何找到Espeak是否结束了演讲
- switch 语句结束和下一条语句之间的时间是否具有确定性(与路径无关)
- 是否有输入类型在输入一定数量的字符后自动结束
- 当没有迭代器失效时,这是否包括结束迭代器?
- 找出静态初始化是否结束
- 如何检测我的Windows应用程序是否已经结束
- 关于检查游戏是否结束的2048年游戏的功能
- 重载指向集合的指针的开始/结束是否是个好主意
- cin函数是否添加了在输入结束时终止的null
- 如何确定输出流链是否已结束?
- 在C++中,是否存在将结束父函数的嵌套函数的返回
- 检查用户是否在倒计时结束前完成了键入
- 使用运算符 new/malloc 分配的内存块是否可以在程序执行结束后持续存在
- Visual C++ 是否需要在'main'函数结束之前暂停应用程序
- C++ - 如果在循环中声明对象,是否在循环结束时调用其析构函数