【发布时间】:2019-01-15 22:13:02
【问题描述】:
我刚刚遇到了将自定义输出运算符与 io-manipulators 相结合的问题。也许我的期望完全偏离了,但如果
std::cout << foo() << "\n";
打印
00
那么我会期待
std::cout << std::left << std::setw(20) << foo() << "!\n"
打印
00 !
但是考虑到这个实现
#include <iostream>
#include <iomanip>
struct foo { int a,b; };
std::ostream& operator<<(std::ostream& out, const foo& f) {
out << f.a << f.b;
return out;
}
int main() {
std::cout << foo() << "\n";
std::cout << std::left << std::setw(20) << foo() << "!";
}
屏幕上打印的是什么
00
0 0!
我基本上看到了两种选择:A) 我的期望是错误的。 B)我改用这个实现:
std::ostream& operator<<(std::ostream& out, const foo& f) {
std::stringstream ss;
ss << f.a << f.b;
out << ss.str();
return out;
}
但是,考虑到大多数时候没有使用 io 操纵器,这似乎是相当大的开销。
在自定义输出运算符中“正确”处理 io-manipulators 的惯用方式是什么?
【问题讨论】:
-
我的解决方案是像您在
B中所做的那样对其进行字符串化。由于输出已经很慢,您甚至可能没有注意到命中。 -
@NathanOliver 嗯...我记得很久以前我想知道我是否应该养成写
foo::toString()或超载ostream::<<的习惯,现在我开始认为它是最好两者兼得 -
那将是另一种方法。然后,如果您较便宜的
operator <<破坏了格式,您可以选择调用更昂贵的to_string。 -
@NathanOliver 我的意思是
<<调用toString,嗯,不知道,必须考虑一下;) -
@user463035818 诸如
set::left、std::setw()等在std::ostream上设置标志的内容通常仅适用于@987654339 上的下一个 调用operator<<使用out << f.a << f.b;时,@fa` 而不是f.b。这是记录在案的行为。如果您想以特定方式格式化多个值,您必须先自己格式化它们,然后将最终结果发送到out,就像使用out << ss.str();一样