1

Consider the following code:

class C{};

std::ostream &operator <<(std::ostream &o, const C &) {
    o.fill('!');
    o.width(8);
    return o << 42;
}

int main() {
    std::cout << C{} << '\n';
    std::cout << 42 << '\n';
    return 0;
}

It outputs:

!!!!!!42

42

I was expecting !!!!!!42 twice because I've changed the state of the provided std::ostream o calling fill and width inside the operator <<, so I used to think that the fill character and the width setted into the operator would leak outside the operator call as if they were sticky properties.

As you can see I don't flush the stream nor re-set the fill character or width so, why (and how) the original behaviour is preserved?

So the question is: How the properties of the ostream are setted back to the previous state after the call to my operator<< for class C?


This doesn't bothers me, I'm happy with this behaviour but I want to understand how it works.

Community
  • 1
  • 1
PaperBirdMaster
  • 12,806
  • 9
  • 48
  • 94
  • `fill` is sticky. `width` is not. You do not see the `fill` characters because they are not being padded to the (now reset) `width`. – underscore_d Jul 17 '15 at 09:57
  • 1
    possible duplicate of [Which iomanip manipulators are 'sticky'?](http://stackoverflow.com/questions/1532640/which-iomanip-manipulators-are-sticky) – underscore_d Jul 17 '15 at 09:59
  • And HOW is reseted the `width`? – PaperBirdMaster Jul 17 '15 at 10:00
  • This is all very well documented. The above link documents which modifiers are sticky and provides a possible rationale for why `width` is not. If you want to know _how_ it is reset, delve into the code of your compiler's standard library. If you want to make your own override, try looking at: http://stackoverflow.com/questions/7248627/setting-width-in-c-output-stream – underscore_d Jul 17 '15 at 10:01

1 Answers1

3

As underscore_d mentioned: width isn't sticky. But actually there is no such attribute stickiness for the iostream classes and their manipulators.

Though, if width would not have been reset by the previous << operator call, the width would also affect the output of \n:

std::cout << std::setw(10) << std::setfill('!') << 42 << '\n';
std::cout << std::setw(10) << std::setfill('!') << 42 << std::setw(10) << '\n';

gives

!!!!!!!!42
!!!!!!!!42!!!!!!!!!

.

ikrabbe
  • 1,909
  • 12
  • 25