Это упражнение для школы, поэтому, пожалуйста, предоставьте только подсказки, а не полные примеры 😉
У меня есть свой манипулятор:
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
(потому что это предлагается сделать в упражнении, которое я должен решить …). Что может быть возможным сценарием, чтобы использовать это ???
Проблема с манипулятором в том, что он возвращает 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';
В дополнение к проблеме, к которой обратился Дитмар: io.flags()
не возвращает
& ios::scientificbool
и преобразование
в 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
может быть актуальным), но вы никогда не знаете.