这是学校的练习,所以请提供一些提示,没有完整的例子; - )
我有自己的操纵者:
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没有如下所述的运算符&lt;&lt;())。
一般来说,我没有得到ios_base& my_manip(basic_ios&)
可能对你有用的东西......你有提示/例子吗?
你们已经帮助了我很多!我仍然不明白,是通过basic_ios
并回馈ios_base
的动机(因为我建议在我必须解决的练习中做...)。什么可能是使用这个??? ???
答案 0 :(得分:4)
操纵器的问题在于它返回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';
答案 1 :(得分:2)
除了Dietmar解决的问题: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
可能是相关的),但你永远不知道。