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