Как использовать этот манипулятор

Это упражнение для школы, поэтому, пожалуйста, предоставьте только подсказки, а не полные примеры 😉

У меня есть свой манипулятор:

template<typename T, typename Tr=char_traits<T> >
ios_base& toggle(basic_ios<T,Tr>& io)
{
if(io.flags() & ios::scientific)
{ io.unsetf(ios::scientific); io.flags(ios::fixed); }
else { io.unsetf(ios::fixed); io.flags(ios::scientific); }
return io;
}

Я написал это, потому что я должен написать манипулятор с формой ios_base& my_manip(basic_ios&),

Если я использую это так (без использования возвращаемого значения):

toggle(cout);

… это отлично работает Но если я использую это так:

toggle(cout) << 54444.6456555 << endl;

Это не работает (потому что std :: ios_base не имеет оператора<<() как указано ниже).

В общем не понимаю чего ios_base& my_manip(basic_ios&) может быть полезно для … У вас есть подсказка / пример?


Вы, ребята, уже очень мне помогли! То, что я до сих пор не понимаю, это мотивация пройти basic_ios и вернуть ios_base (потому что это предлагается сделать в упражнении, которое я должен решить …). Что может быть возможным сценарием, чтобы использовать это ???

6

Решение

Проблема с манипулятором в том, что он возвращает std::ios_base& а не std::ostream& Вы можете написать в. Вы мог изменить манипулятор, чтобы взять std::ostream& в качестве параметра и вернуть полученную ссылку. Однако класс потока вывода определяет операторы вывода, которые принимают указатели на функции:

std::ostream& std::ostream::operator<< (std::ios_base& (*)(std::ios_base&)) { ... }

То есть вы можете просто вставить манипуляторы так, как вы это делаете, например, std::hex:

std::cout << std::hex << 123 << ' ' << std::dec << 123 << '\n';
4

Другие решения

В дополнение к проблеме, к которой обратился Дитмар: io.flags()
& ios::scientific
не возвращает boolи преобразование
в bool вероятно, не делает то, что вы хотите. Тебе что-то нужно
вдоль линий:

if ( (io.flags() & ios::floatfield) == ios::fixed ) {
io.setf( ios::scientific, ios::floatfield );
} else if ( (io.flags() & ios::floatfield) == ios::scientific ) {
io.setf( ios::fixed, ios::floatfield );
} else {
//  Whatever you want to happen first time around...
}

Несмотря на то, что является частью переменной с типом с именем ...flags,
floatfield это не флаг, а поле, которое может взять на
минимум три значения: fixed, scientific и его значение по умолчанию
в котором ни один из них не установлен. (basefield а также
adjustfield вести себя аналогично.)

Также обратите внимание на использование формы с двумя аргументами ios::setf; это
разработан специально для этих параметров формата битового поля, и
сбрасывает биты во втором аргументе перед установкой
в первом.

Я мог бы добавить, что вы, вероятно, делаете не хочу позвонить io.flags
в вашем манипуляторе; это устанавливает все флагов форматирования в
значение, которое вы даете, эффективно сбрасывая все остальные форматирования
флаги. Если вы выводите только с плавающей запятой, это может не
быть проблемой (хотя showpos, showpoint, uppercase а также
возможно unitbuf может быть актуальным), но вы никогда не знаете.

2

По вопросам рекламы [email protected]