暂时覆盖输出流行为
Temporarily override output stream behavior
假设我有一个字符向量(或者只是一个迭代器对),我想将其打印到ostream。现在,我不仅想要打印它 - 我希望它具有特定类型的间距,我想要字符值的不同表示形式,而不仅仅是将它们脱口而出到终端(例如,如果可打印,则字符和转义的 2 位或十六进制代码。
现在我不想编写自己的自定义代码超出最低限度 - 即只是一点胶水和
void foo(ostream& os, char c) {
os << c << ' ' << as_hex(c);
}
(这就像运算符的自定义重载<<没有返回。
我不想在 vecotr 上循环,对于每个角色手动调用 abve,我希望它的行为和看起来好像我只是在暂时更改后者的属性后将我的向量传输到我的输出流。但有时我希望流恢复正常行为,即使对于相同的向量也是如此。
这可以合理/习惯地完成吗?
我假设您了解运算符重载,您的主要问题是如何告诉运算符使用哪个格式选项,即如何在流中存储任意信息。
任何派生自std::ios_base
(所有标准流类)的方法都有.iword()
方法,该方法从某些内部存储.pword()
返回对long
的引用,并返回对void*
的引用。这些调用的唯一索引可以通过调用std::ios_base::xalloc()
来获取
使用流存储更改输出操作行为的示例:
#include <iostream>
#include <vector>
const int vprint_index = std::ios_base::xalloc();
std::ostream& operator<<(std::ostream& out, std::vector<char> vec)
{
if (out.iword(vprint_index) == 0) {
for(char c: vec)
out << c;
return out;
}
out.iword(vprint_index) = 0;
out << '{';
bool first = true;
for(char c: vec) {
if(!first)
out << ", ";
first = false;
out << c;
}
return out << '}';
}
int main()
{
std::vector<char> vector {'f', 'o', 'o'};
std::cout << vector << 'n';
std::cout.iword(vprint_index) = 1;
std::cout << vector << 'n';
std::cout << vector << 'n';
}
噗噗��
{f, o, o}
噗噗��
对于暂时的重载,我认为做一些像 iomanip
这样的事情会很好。这将允许做类似的事情
int main()
{
std::vector<char> v{'a', 'b'};
/* v should be printed using foo_vector_print, perhaps
* next invocation should use a different format. */
std::cout << foo_vector_print() << v << std::endl;
}
这个想法是有这样一种形式:
stream << manip << vector;
哪里
-
stream << manip
将返回存储对流的引用的类的对象。 -
... << vector
将使用特定格式打印,然后返回对原始流的引用。
以下程序演示如何执行此操作:
#include <iostream>
#include <vector>
namespace detail
{
// A dummy class in detail namespace, simply records the original ostream object.
struct foo_vector_printer_imp
{
std::ostream *m_os;
};
};
// This particular implementation simply prints out the vectors size.
std::ostream &operator<<(detail::foo_vector_printer_imp imp, const std::vector<char> &v)
{
*imp.m_os << v.size();
return *imp.m_os;
}
struct foo_vector_print{};
/* The result of piping a foo_vector_print into an ostream,
* is a foo_vector_printer_imp object recording the ostream */
detail::foo_vector_printer_imp operator<<(std::ostream &os, const foo_vector_print &)
{
detail::foo_vector_printer_imp imp;
imp.m_os = &os;
return imp;
}
int main()
{
std::vector<char> v{'a', 'b'};
std::cout << foo_vector_print() << v << std::endl;
}
好吧,你必须在某个地方编写你的自定义代码。矢量的内容不会自行写入std::ostream
。
从外观上看,您实际上是在问如何使用<<
运算符在std::vector<char>
上进行操作。以下示例应帮助您入门:
#include <iostream>
#include <vector>
std::ostream &operator<<(std::ostream &o, const std::vector<char> &v)
{
// Fill in the blanks here.
return o;
}
// Example:
int main()
{
std::vector<char> v;
std::cout << v;
return 0;
}
相关文章:
- 如何在C++中编写 ostream 的向量,它接收所有不同的输出流,如 cout、ostringstream 和 ofs
- 在输出流中插入换行符
- 在类外部重载输入和输出流
- 通用容器的输出流
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- 使输出流式处理运算符适用于 boost::variant<std::vector<int>、int、double 的正确方法是什么>
- 获取C++输出流中元素的大小
- 用于了解输入和输出流缓冲区实际工作方式的程序
- 控制多线程程序中的输出流
- 为什么输出流首选" "而不是""?
- C++ 输出流运算符 <<() 中的字符何时加宽?
- 音频缓冲区列表,用于输出流格式已压缩的 AUHAL 单元
- 如何将值发送到标准输出流并在另一个程序中访问这些值
- 我必须如何将OpenCV输出流到我自己的远程C GUI
- 如何为提升日志和自定义类型定义输出流运算符
- 修改视频帧并将其发送回视频输出流
- 组合输入和输出流
- C++ 中的递增/递减和输出流运算符优先级
- C++输出流到文件不起作用
- 输出流中的运算符优先级C++