重载运算符将函数指针作为参数,如何检索函数指针的参数
我有一个重载的运算符 << 试图让它像这样工作,
mystream<<hex<<10;
我重载了方法,
mytream& operator<<(ios_base& (*m) ios_base&)
每当遇到十六进制时都会调用该方法,因为方法中传递的参数是与十六进制相同类型的函数指针或像其他一些输出操纵器(如 dec、oct)一样。
我有两个问题
1) 如何检索十六进制将要操作的参数,在本例中为 10
2) 我如何知道 << 正在为十六进制调用运算符,而不是为八进制和十进制等其他操纵器函数调用
谢谢
i have an overloaded operator << trying to make it work like this
mystream<<hex<<10;
i have overloaded method
mytream& operator<<(ios_base& (*m) ios_base&)
This gets called whenever hex is encountered cause the parameter passed in the method is a function pointer of type same as hex or like some other output manipulators like dec, oct.
i have two problems
1) how do i retrieve the parameter the hex would be operating on, in this example 10
2) how do i know that the << operator is being called for hex and not other manipulator function like oct and dec
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
1) 十六进制不对参数 10 进行操作。
<<
运算符从左到右关联,这意味着您的代码与以下内容相同:因此您的重载必须返回一个对象,当10 被移入其中,以十六进制打印(或者如果不打印,则将数据写入某处)。 正如大家所说,这是通过在流对象本身中保存标志,然后返回
*this
来完成的。 使用标志的原因正是因为“10”尚不可用,因为第二个<<
尚未评估。 第一个<<
运算符调用无法打印任何内容 - 它只需要在调用第二个运算符时做好准备。2) hex 是一个函数。 它可以与其他函数进行比较:
除非你通常不想这样做,否则你想要默认行为,类似于:(
我可能是错的,我从来没有看过实现,但一般想法是操作符调用操纵器函数,操纵器(线索在名称中)操纵流)。
std::hex
在其参数上设置std::ios::hex
格式标志。 然后在您的operator<<(int)
重写中,如果您有的话,请通过调用flags()
检查格式标志。3)接受参数的操纵器也是函数,但它们的返回类型未指定,这意味着它取决于实现。 查看我的 gcc
iomanip
标头,setw
返回_Setw
,set precision
返回_Set precision
,等等。 Apache 库的做法不同,更像是无参数操纵器。 您可以使用参数化操纵器进行的唯一可移植的操作是将它们应用到带有operator<<
的 iostream,它们没有定义自己的成员函数或运算符。因此,就像
hex
一样,要处理setw
,您应该从std::ios_base
继承,依赖于operator<<
code> 实现由您的库提供,然后当您格式化数据时,请使用width()
、precision()
检查您自己的宽度、精度等,等等,在ios_base
上运行。也就是说,如果出于某种奇怪的原因您需要拦截这些操纵器的标准
operator<<
,您可能可以将一些东西放在一起,沿着这些思路:不过,我确实认为这是一个bodge。 您实际上不应该干扰流操纵器,只需让您的基类完成工作并查找结果即可。
1) hex is not operating on the parameter 10.
<<
operators associate left-to-right, which means your code is the same as:So your overload has to return an object which, when 10 is shifted into it, prints in hex (or if not prints, writes data somewhere). As everyone says, this is done by saving flags in the stream object itself, then returning
*this
. The reason flags are used is precisely because the "10" is not available yet, since the second<<
has not been evaluated yet. The first<<
operator call cannot print anything - it just has to get ready for when the second one is called.2) hex is a function. It can be compared with other functions:
Except you don't normally want to do that, you want the default behaviour, which is something like:
(I may be wrong on that, I've never looked at the implementation, but the general idea is that the operator calls the manipulator function, and the manipulator (the clue's in the name) manipulates the stream).
std::hex
sets thestd::ios::hex
format flag on its parameter. Then in youroperator<<(int)
override, if you have one, check the format flags by callingflags()
.3) Manipulators which take paramers are functions too, but their return types are unspecified, meaning it's up to the implementation. Looking at my gcc
iomanip
header,setw
returns_Setw
,setprecision
returns_Setprecision
, and so on. The Apache library does it differently, more like the no-args manipulators. The only thing you can portably do with parameterized manipulators is apply them to an iostream withoperator<<
, they have no defined member functions or operators of their own.So just like
hex
, to handlesetw
you should inherit fromstd::ios_base
, rely on theoperator<<
implementation provided by your library, then when you come to format your data, examine your own width, precision, etc, using thewidth()
,precision()
, etc, functions onios_base
.That said, if for some bizarre reason you needed to intercept the standard
operator<<
for these manipulators, you could probably bodge something together, along these lines:I do consider this a bodge, though. You're not really supposed to interfere with stream manipulators, just let your base class do the work and look up the results.
当使用
hex
或oct
或dec
调用operator<<
时,请在中设置一个标志mystream
对象。 当使用数字调用operator<<
时,检查是否设置了这些标志。 如果是这样,请将数字转换为十六进制/八进制/十进制并显示。When
operator<<
gets called withhex
oroct
ordec
, set a flag in yourmystream
object. Whenoperator<<
is called with a number, check to see if any of these flags are set. If so, convert the number to hex/octal/decimal and display it.在回答第二个问题时,参数 m 是指向操纵器函数的指针。 您可以检查它是否不为 null,然后调用该函数并传递
*this
。 正如 Zifre 建议的那样,hex()
就像在传递的流对象中设置一个标志一样简单。 然后在处理整数时,检查流对象中的标志是否设置,并进行相应的输出。这就是标准库实现其操纵器功能的方式。
In answer to your second question, the parameter
m
is a pointer to the manipulator function. You can check that it's not null, then call that function, passing*this
.hex()
is as simple as setting a flag in the passed stream object, as Zifre suggested. Then when processing the integer, check if the flag in the stream object is set, and output accordingly.This is how the standard library implements its manipulator functions.
在您的示例中,十六进制对流进行操作(更改其状态),而不是对以下参数进行操作。 hex 与其他 << 没有任何概念或任何关系。 来电。
看看其他 io 操纵器是如何实现的将会对解决问题大有帮助。
In your example, hex operates on (changes the state of) the stream, not the following parameters. hex has no notion of, or any relation to other << calls.
Looking at how other io manipulators are implemented would go a long way to clearing things up.
您应该操作 ios_base::flags
http://www.cplusplus.com/reference /iostream/ios_base/flags/
这是标准十六进制的作用。
You should be manipulating ios_base::flags
http://www.cplusplus.com/reference/iostream/ios_base/flags/
which is what the standard hex does.