Что за дело с setw ()? - PullRequest
       36

Что за дело с setw ()?

16 голосов
/ 06 мая 2011

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

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

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

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

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

Хорошо, хорошо.

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

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

Ответы [ 2 ]

5 голосов
/ 06 мая 2011

Решения о том, какие манипуляторы должны влиять только на следующую операцию, по-видимому, основаны на логических и эмпирических наблюдениях о том, что лучше учитывает общие функциональные потребности, и, следовательно, программисту будет легче писать и понимать правильно.

Следующие пункты мне кажутся актуальными:

  • some_stream << x должен просто работать правильно большую часть времени
  • большая часть кода, который устанавливает ширину, будет сразу или очень скоро после этого передавать потокзначение, поэтому несвязанный код может предположить, что не будет некоторого «ожидающего» значения ширины, влияющего на его вывод
  • setfill() не имеет значения , если нет ожидающего setw(), поэтому выиграно 't отрицательно влияет на оператор some_stream << x, стоящий перед нашим списком
    • , только когда явно задана ширина, программист может / должен рассмотреть вопрос о том, подходит ли также состояние символа заполнения, основываясь на своих знаниях о большем контексте вызова
  • очень часто для набора значений используется одна и та же заливкаracter
  • другие манипуляторы, такие как hex и oct, являются постоянными, но они обычно используются в блоке кода, который либо выводит предыдущее состояние, либо (неприятно, но проще) устанавливает его обратно в десятичное значение

Исходящая из этого точка, которая отвечает на ваш вопрос ...

  • , если бы setw() было постоянным, его необходимо будет сбрасывать между каждым оператором потоковой передачидля предотвращения нежелательной заливки ...
4 голосов
/ 06 мая 2011

Я вижу это так: вы всегда можете сделать что-то, как показано ниже, если хотите, чтобы это применялось равномерно.

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

но если это было липким, как вы упомянули:

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

, и если я хотел, чтобы каждая строка имела разную ширину, я должен был бы установить ширину.

Такпо сути, оба подхода почти одинаковы, и я хотел бы или не хотел бы их в зависимости от того, что я делаю сейчас.

...