1

考虑以下代码:

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;
}

它输出:

!!!!!!42

42

我期待!!!!!!42两次,因为我已经改变了提供的std::ostream o调用fillwidth内部的状态operator <<,所以我曾经认为填充字符和设置到运算符中的宽度会泄漏到运算符调用之外,就好像它们是粘性属性一样。

如您所见,我没有刷新流,也没有重新设置填充字符或宽度,为什么(以及如何)保留原始行为?

所以问题是:在调用 my forostream之后,如何将属性设置回之前的状态?operator<<class C


这并不困扰我,我对这种行为很满意,但我想了解它是如何工作的。

4

1 回答 1

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!!!!!!!!!

.

于 2015-07-17T10:10:22.497 回答