c++ - 如何在自定义对象的 << 运算符中添加自定义前缀
问题描述
有没有办法在operator<<
我实现的对象中添加自定义前缀?
前任:
class A {
public:
std::string id;
int count;
};
std::ostream &operator<<(std::ostream &os, const A &a)
{
os << os.prefix() << "Id: " << a.id << "\n";
os << os.prefix() << "Count: " << a.count << "\n";
return os;
}
如果我做这样的事情:
A a;
a.id = "foo";
a.count = 1;
std::cout << a << std::endl;
输出将是:
Id: foo
Count: 1
我想做类似的事情:
std::cout << set_prefix(" -") << a << std::endl;
std::cout << set_prefix("==>") << a << std::endl;
要获得这样的输出:
-Id: foo
-Count: 1
==>Id: foo
==>Count: 1
一个建议是使用std::setfill
and os.fill
,但std::setfill
将单个char
作为参数,我需要一个自定义字符串。
解决方案
查看operator<<(std::basic_ostream)文档,我发现了这个:
在插入之前,首先使用 扩展所有字符
os.widen()
,然后按如下方式确定填充:如果要插入的字符数小于os.width()
,则将足够的副本os.fill()
添加到字符序列中以使其长度相等os.width()
。如果(out.flags()&std::ios_base::adjustfield) == std::ios_base::left
,则将填充字符添加到输出序列的末尾,否则将它们添加到输出序列之前。插入后,width(0)
调用取消 的效果(std::setw
如果有)。
因此,对我有用的解决方案是在开始时保存流的原始宽度,而不是在必要时恢复它们。
std::ostream &operator<<(std::ostream &os, const A &a)
{
auto w = os.width();
os << std::setw(w) << "" << "Id: " << a.id << "\n";
os << std::setw(w) << "" << "Count: " << a.count;
return os;
}
然后:
std::cout << a << std::endl;
std::cout << std::setw(4) << a << std::endl;
std::cout << std::setfill('>') << std::setw(2) << a << std::endl;
给出以下输出:
Id: foo
Count: 1
Id: foo
Count: 1
>>Id: foo
>>Count: 1
解决方案
也许有点矫枉过正,但你可以使用这样的东西:
#include <iostream>
#include <sstream>
struct line_buffered_stream {
std::ostream& out;
std::stringstream ss;
std::string prefix;
line_buffered_stream(std::ostream& out,std::string prefix) :
out(out),prefix(prefix) {}
template <typename T>
auto operator<<(const T& t) -> decltype(this->ss << t,*this) {
ss << t;
return *this;
}
~line_buffered_stream(){
std::string line;
while (std::getline(ss,line)){
out << prefix << line << "\n";
}
}
};
int main() {
line_buffered_stream(std::cout,"==>") << "a\nb\n";
line_buffered_stream(std::cout,"-->") << "a\nb\n";
}
输出:
==>a
==>b
-->a
-->b
请注意,上面的实现并不打算用作其他任何东西,只是一个临时的,其生命周期仅限于一行代码。如果您不喜欢这样,则必须添加一些机制来刷新流,std::cout
以免等到调用析构函数。
推荐阅读
- python-3.x - 将逗号分隔的字符串转换为熊猫列表
- javascript - SVG 过滤器置换作为整个网站的覆盖
- angular - 加载组件时不显示值
- android - 为什么我添加本地源依赖时Android Studio gradle同步持续超过10分钟(无需下载)
- c - 我在使用 realloc 时遇到了意外的行为
- whmcs - 调用“OpenTicket”时出现 WHMCS API 错误
- google-app-engine - 从另一个 API 访问谷歌机器学习 API
- python-3.x - 无法使用 python 在 Linux 服务器中创建文本文件
- google-cloud-platform - Google Cloud Functions 的单元测试
- php - Symfony 相关验证或验证组