如何使用这个操纵器

时间:2013-12-30 15:40:14

标签: c++ manipulators

这是学校的练习,所以请提供一些提示,没有完整的例子; - )

我有自己的操纵者:

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的动机(因为我建议在我必须解决的练习中做...)。什么可能是使用这个??? ???

2 个答案:

答案 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不是标志,而是可以接受的字段 至少三个值:fixedscientific及其默认值 其中都没有设置。 (basefieldadjustfield行为相似。)

请注意使用ios::setf的两个参数形式;它是 专门为这些位域格式参数而设计的 在设置之前,重置第二个参数中的位 在它的第一个。

我可能会补充一点,你可能想要致电io.flags 在你的操纵者;这会将所有格式化标志设置为 您提供的值,有效地重置所有其他格式 标志。如果您只输出浮点数,则可能不会 是一个问题(虽然showposshowpointuppercase和 可能unitbuf可能是相关的),但你永远不知道。