Which iomanip manipulators are 'sticky'?

前端 未结 3 1103
醉梦人生
醉梦人生 2020-11-22 16:01

I recently had a problem creating a stringstream due to the fact that I incorrectly assumed std::setw() would affect the stringstream for every ins

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-22 16:55

    The reason that width does not appear to be 'sticky' is that certain operations are guaranteed to call .width(0) on an output stream. Those are:

    21.3.7.9 [lib.string.io]:

    template
      basic_ostream&
        operator<<(basic_ostream& os,
                   const basic_string& str);
    

    22.2.2.2.2 [lib.facet.num.put.virtuals]: All do_put overloads for the num_put template. These are used by overloads of operator<< taking a basic_ostream and a built in numeric type.

    22.2.6.2.2 [lib.locale.money.put.virtuals]: All do_put overloads for the money_put template.

    27.6.2.5.4 [lib.ostream.inserters.character]: Overloads of operator<< taking a basic_ostream and one of the char type of the basic_ostream instantiation or char, signed char or unsigned char or pointers to arrays of these char types.

    To be honest I'm not sure of the rationale for this, but no other states of an ostream should be reset by formatted output functions. Of course, things like badbit and failbit may be set if there is a failure in the output operation, but that should be expected.

    The only reason that I can think of for resetting the width is that it might be surprising if, when trying to output some delimited fields, your delimiters were padded.

    E.g.

    std::cout << std::setw(6) << 4.5 << '|' << 3.6 << '\n';
    
    "   4.5     |   3.6      \n"
    

    To 'correct' this would take:

    std::cout << std::setw(6) << 4.5 << std::setw(0) << '|' << std::setw(6) << 3.6 << std::setw(0) << '\n';
    

    whereas with a resetting width, the desired output can be generated with the shorter:

    std::cout << std::setw(6) << 4.5 << '|' << std::setw(6) << 3.6 << '\n';
    

提交回复
热议问题