gpt4 book ai didi

c++ - 如何处理自定义输出运算符中的 iomanips?

转载 作者:行者123 更新时间:2023-11-30 02:18:51 25 4
gpt4 key购买 nike

我刚刚遇到了将自定义输出运算符与 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 操纵器的惯用方法是什么?

最佳答案

恐怕没有简单的答案。如果您只需要处理 std::setwstd::left,那么您的解决方案是惯用的,但是对于其他操作,您必须决定格式化程序的行为。

想象一下,例如,如果您的结构有 float 而不是整数:

struct foo { float a,b; };

然后,您的用户尝试这样做:

const long double pi = std::acos(-1.L);
std::cout << std::setprecision(10) << foo{0.0f, pi} << "!\n"

这是您必须决定的时候:您是要尊重输出流的精度属性,还是要忽略它?您当前的实现会忽略它,因为它在另一个流中进行实际转换。

为了尊重精度属性,您必须复制它:

std::ostream& operator<<(std::ostream& out, const foo& f) {
std::stringstream ss;
ss.precision(out.precision());
ss << f.a << f.b;
out << ss.str();
return out;
}

对于整数的情况,您还必须考虑是否遵守 std::setbase

同样的推理也适用于其他操纵器,例如 std::setfill

关于c++ - 如何处理自定义输出运算符中的 iomanips?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51750191/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com