Что за дело с setw()?
Недавно меня укусил тот факт, что ios_base::width
и / или setw
Манипулятор должен быть сброшен с каждым элементом, записанным в поток.
То есть вы должны сделать это:
while(whatever)
{
mystream << std::setw(2) << myval;
}
Вместо этого:
mystream.width(2);
while(whatever)
{
mystream << myval;
}
Хорошо.
Но кто-нибудь знает, почему было принято это дизайнерское решение? Есть ли какое-то обоснование, которое я упускаю, или это просто темный угол стандарта?
Другие модификаторы форматирования потока (как упомянуто в связанном вопросе SO) являются "липкими", в то время как setw
не является.
2 ответа
Я вижу это так: вы всегда можете сделать что-то, как показано ниже, если хотите, чтобы это применялось равномерно.
int width =2;
while(whatever)
{
mystream << std::setw(width) << myval;
}
но если это было липким, как вы упоминаете:
mystream.width(2);
while(whatever)
{
mystream << myval;
}
и если я хотел разную ширину каждой строки, я должен сохранить ширину установки.
По сути, оба подхода практически одинаковы, и я хотел бы или не хотел их в зависимости от того, что я делаю сейчас.
Решения о том, какие манипуляторы должны влиять только на следующую операцию, по-видимому, основаны на логических и эмпирических наблюдениях о том, что лучше учитывает общие функциональные потребности, и, следовательно, программисту будет легче писать и понимать правильно.
Следующие пункты кажутся мне актуальными:
some_stream << x
должен просто работать правильно большую часть времени- большая часть кода, который устанавливает ширину, будет немедленно или очень скоро после этого передавать значение, поэтому несвязанный код может предположить, что не будет никакого "ожидающего" значения ширины, влияющего на его вывод
setfill()
не имеет отношения, если нет ожидающихsetw()
, поэтому не будет отрицательно влиять наsome_stream << x
Заявление возглавляет наш список- только когда явно задана ширина, программист может / должен рассмотреть вопрос о том, подходит ли состояние символа заполнения, основываясь на своем знании более широкого контекста вызова
- для набора значений очень часто используется один и тот же символ заполнения
- другие манипуляторы, такие как
hex
а такжеoct
являются постоянными, но их использование обычно происходит в блоке кода, который либо выводит предыдущее состояние, либо (неприятно, но проще) устанавливает его обратно в десятичное
Точка, ведущая из этого, которая отвечает на ваш вопрос...
- если
setw()
были постоянными, это должно было бы быть сброшено между каждым оператором потоковой передачи, чтобы предотвратить нежелательное заполнение...