Подтвердить что ты не робот

Какая сделка с setw()?

Недавно я был укушен фактом, что ios_base::width и/или манипулятор setw должны быть reset с каждым элементом, записанным в поток.

То есть вы должны сделать это:

while(whatever)
{
    mystream << std::setw(2) << myval;
}

Вместо этого:

mystream.width(2);
while(whatever)
{
    mystream << myval;
}

Хорошо, отлично.

Но кто-нибудь знает, почему было принято это дизайнерское решение? Есть ли какое-то обоснование, которое мне не хватает, или это просто темный угол стандарта?

Другие модификаторы форматирования потока (как указано в связанном вопросе SO) являются "липкими", а setw - нет.

4b9b3361

Ответ 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 между каждым потоковым оператором...