在 operator<< 中为整个向量设置 precision/field 宽度

Setting precision/field width in operator<< for an entire vector

下面的代码将向量打印到 std::cout

struct vect {
    double x;
    double y;
};
std::ostream& operator<<(std::ostream& os, vect v){
    os << "[" << v.x << " " << v.y << "]";
    return os;
}

int main(){
    vect v = {1.0, 2.0};
    std::cout << v << std::endl;
    return 0;
}

有什么好的方法可以控制每个字段的width/precision?我可以在 operator<<:

中对其进行硬编码
std::ostream& operator<<(std::ostream& os, vect v){
    os << "[" << std::setprecision(3) << std::setw(7) << v.x << " " << std::setprecision(3) << std::setw(7) << v.y << "]";
    return os;
}

但我更愿意从外部控制它:

std::cout << std::setprecision(3) << std::setw(7) << v << std::endl;

不过我认为这只会设置向量第一个字段的精度和宽度。

我的想法是在 operator<< 的开头先 "getw" 和 "getprecision",然后将它们持久化到其他字段。有没有办法从流中检索这些东西,这个基本设计是否基于正确的假设? (我对 iomanipulators 的工作原理不是很有信心;我只知道在数据之前发送 std::setw。)

这就是我所做的。是声音设计吗?

std::ostream& operator<<(std::ostream& os, vect v){
    auto p = os.precision();
    auto w = os.width();
    os << "[" << std::setprecision(p) << std::setw(w) << v.x << " " << std::setprecision(p) << std::setw(w) << v.y << "]";
    return os;
}

However I think this would only set the precision and width for the first field of the vector.

我认为您应该在花更多时间尝试 "solve" 之前验证这一点。

(不是真正的答案,但我不能在评论中引用等)

如评论所述,setprecision 仍然存在,但 setw 没有。

假设您希望 setw 应用于组合类型中的每个单独字段,但不应用于其周围的格式化字符。为此,请查看宽度 属性,然后为每个数字字段设置它。

#include <iostream>
#include <iomanip>

struct coordinate {
    double x;
    double y;
};

std::ostream& operator<<(std::ostream& os, coordinate p) {
    auto w = os.width();
    os << std::setw(0) << "["  // we don't want the width yet
       << std::setw(w) << p.x  // set width on specific field
       << " " 
       << std::setw(w) << p.y  // set width on specific field
       << "]";
    return os;
}

int main() {
    coordinate value = { 1.000019, 2.000019 };
    std::cout << std::setprecision(3) << std::setw(7) << value << std::endl;
    std::cout << std::setprecision(6) << std::setw(7) << value << std::endl;
    std::cout << std::setprecision(1) << std::setw(3) << value << std::endl;
    return 0;
}

输出:

[      1       2]  
[1.00002 2.00002]  
[  1   2]