2009-07-16 132 views
1

我有一个重载操作< <试图使它像这样重载运算符采用函数指针作为参数,如何取回函数指针的参数

mystream<<hex<<10; 

我重载方法

mytream& operator<<(ios_base& (*m) ios_base&) 
工作

只要遇到十六进制,就会被调用,导致在方法中传递的参数是一个类型与十六进制类似的函数指针,或者像dec,oct等其他输出操纵符。

我有两个问题

1)我如何获取十六进制将上操作的参数,在这个例子中10

2)我怎么了< <运营商被要求知道十六进制和像十月和DEC没有其他机械手功能

感谢

回答

7

1)己未在参数10 <<运营商关联操作左到右的,这意味着您的代码是相同的:

(mystream<<hex)<<10; 

所以你的过载必须返回一个物体,当10被移入时,以十六进制打印(或者如果不打印,则在某处写入数据)。正如大家所说,这是通过在流对象本身中保存标志完成的,然后返回*this。使用原因标志正是因为“10”尚未提供,因为第二个<<尚未评估。第一个<<操作员调用不能打印任何东西 - 只需要在第二个调用时做好准备。

2)十六进制是一个函数。它可以与其它功能比较:

ostream &operator<<(ostream &s, ios_base& (*m)(ios_base &)) { 
    if (m == hex) { 
    } else if (m == oct) { 
    } else if (m == dec) { 
    } 
} 

除非你通常不希望这样做,你想要的默认行为,这是一样的东西:

ostream &operator<<(ostream &s, ios_base& (*m)(ios_base &)) { 
    return m(s); 
} 

(我可能是错的我从来没有看过实现,但总体思路是操作员调​​用操纵器函数,而操纵器(名称中的线索)操纵流。

std::hex在其参数上设置std::ios::hex格式标志。然后在operator<<(int)覆盖中,如果有覆盖,请通过调用flags()来检查格式标志。

3)带参数的机械手也是函数,但它们的返回类型没有指定,这意味着它的实现。看看我的gcc iomanip标题,setw返回_Setw,setprecision返回_Setprecision,依此类推。 The Apache library does it differently,更像无参数操纵器。你可以使用参数化操纵器做的唯一事情就是将它们应用于一个带有operator<<的iostream,它们没有定义的成员函数或它们自己的操作符。

所以就像hex,处理setw你应该从std::ios_base继承,依赖于你的库提供的operator<<实施,那么当你来格式化数据,检查自己的宽度,精度等,使用width()precision()等,功能ios_base

也就是说,如果出于某种奇怪的原因,你需要拦截的标准operator<<这些操纵,你很可能bodge东西一起,沿着这些线路:

template <typename SManip> 
mystream &operator<<(mystream &s, SManip m) { 
    stringstream ss; 
    // set the state of ss to match that of s 
    ss.width(s.width()); 
    ss.precision(s.precision()); 
    // etc 
    ss << m; 
    // set the state of s to match that of ss 
    s.width(ss.width()); 
    s.precision(ss.precision()); 
    // etc 
    return s; 
} 

我不认为这是一个bodge,虽然。你并不是真的应该干涉流操纵器,只要让你的基类做工作,并查找结果。

0

operator<<被称为与hexoctdec,在您的mystream对象中设置一个标志。当用号码调用operator<<时,请检查是否设置了这些标志中的任何一个。如果是这样,将数字转换为十六进制/八进制/十进制并显示它。

+0

这是一个递归的答案“当operator <<以十六进制或十进制或十进制调用时,在mystream对象中设置一个标志”时,第二个问题是如何知道调用了哪些函数? “ ”将数字转换为十六进制/八进制/十进制并显示它。“如何在我的重载操作符函数中获取该数字,即第一个问题 – Kazoom 2009-07-16 19:27:26

+1

您应该在* another *重载操作符函数中获取数字,其中一个会得到int – 2009-07-16 20:38:32

0

在回答你的第二个问题时,参数m是一个指向操纵器函数的指针。您可以检查它是否为空,然后调用该函数,传递*this。如Zifre所示,hex()与在传递的流对象中设置标志一样简单。然后在处理整数时,检查流对象中的标志是否已设置,并相应地输出。

这是标准库如何实现其操纵器功能。

+1

为什么选择down表决? – 2009-07-16 21:06:20

0

在您的示例中,十六进制操作(更改状态)流,而不是以下参数。十六进制与其他< <调用没有任何关系或任何关系。看看其他io操纵器是如何实现的,将会对清除问题有很长的路要走。