c++笔记:流控制操作符的作用域

1. 流控制符总结

std::setw 是唯一的"纯一次性"宽度控制符

其他所有格式操纵符基本都是持久的

有两类操作符:无参 vs 有参操纵符,实现原理说明如下:

  • 无参操纵符(以 std::fixed 为例)

    cpp 复制代码
    // 标准库中的定义(简化)
    std::ios_base& fixed(std::ios_base& str) {
        str.setf(std::ios_base::fixed, std::ios_base::floatfield);
        return str;
    }
    
    // 使用方式
    std::cout << std::fixed;  
    // 实际执行:std::fixed(std::cout) → 修改流的格式标志
  • 有参操纵符(以 std::setw 为例)

    cpp 复制代码
    // 标准库中的定义(简化)
    struct _Setw {
        int _M_n;
        _Setw(int n) : _M_n(n) {}
    };
    
    _Setw setw(int n) {
        return _Setw(n);  // 返回临时对象
    }
    
    // 流操作符重载
    std::ostream& operator<<(std::ostream& os, const _Setw& manip) {
        os.width(manip._M_n);  // 设置宽度(一次性)
        return os;
    }
    
    // 使用方式
    std::cout << std::setw(10);
    // 实际执行:创建临时对象 → 调用重载的 operator<< → 设置宽度

2. 举例

cpp 复制代码
// 每次需要宽度时,显式写明
std::cout << std::setw(8) << std::left << name
          << std::setw(4) << age << "\n";
// 即使 left 是持久的,setw 仍需每次设置

3. 恢复默认状态(避免污染后续输出)

cpp 复制代码
// 保存当前状态
std::ios::fmtflags oldFlags = std::cout.flags();
// 修改格式...
std::cout << std::fixed << std::setprecision(2) << value;
// 恢复
std::cout.flags(oldFlags);