C++重载运算符解析
g++ 4.4.5
我有一个类扩展了 std::ofstream 类以添加一些功能。
MyStream& MyStream::operator<<(const bool& val) {
if(this->pos == 8) {
this->pos = 0;
ofstream::operator<<(this->curbyte); //call the parent method
}
curbyte = curbyte + (val << pos++);
return *(this);
}
它基本上允许您将各个位写入为布尔值,然后它将使用父 << 写入每组 8 个位。方法。我必须在这里使用此调用语法,因为我正在调用基本方法,但在我使用此类的实际主方法中,我尝试调用以下行:
bout << (unsigned char) 255u;
我想调用 <<方法已经为 ofstream 和 unsigned char 定义,但它给了我一个很长的模糊重载错误,列出了已经为 ofstream (char, unsigned char,signed char) 和我自己的 bool 方法定义的所有与 char 相关的候选者,即使我显式转换为 char。不过,我确实设法让它与以下内容一起工作:
bout.operator<<((unsigned char) 255u);
这必须与 g++ 如何进行隐式转换有关(我的猜测是,在第一种情况下,在我的用户定义的转换之后,还有一个可能的转换,这使得它变得含糊不清)函数调用语法避免)。有谁确切知道为什么会发生这种情况,或者是否有更好的语法可以避免该错误?
g++ 4.4.5
I have a class that extends the class std::ofstream to add some functionality.
MyStream& MyStream::operator<<(const bool& val) {
if(this->pos == 8) {
this->pos = 0;
ofstream::operator<<(this->curbyte); //call the parent method
}
curbyte = curbyte + (val << pos++);
return *(this);
}
which basically allows you to write individual bits as bools and then it will write each set of 8 using the parent << method. I had to use this calling syntax here because I was calling the base method but in my actual main method where I use this class I tried to call the following line:
bout << (unsigned char) 255u;
which I want to have call the << method already defined for ofstream and unsigned char but it gives me a long ambiguous overload error listing all the char related candidates already defined for ofstream (char, unsigned char, signed char) and my own bool method, even though I explicitly cast to char. However I did manage to get it to work with the following:
bout.operator<<((unsigned char) 255u);
This must have something to do with how g++ does the implicit casting (my guess is there's one more possible cast after my user-defined cast in the first case which makes it ambiguous that the function call syntax avoids). Does anyone know exactly why this is happening or if there's a better syntax that avoids the error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
std::ostream
中定义为成员函数的运算符<<
不是虚拟
。您的运算符<<
隐藏此函数的所有基类版本,因此它们对于重载解析不可见。然而,定义为自由函数的运算符<<
是可见的。采用
char
、unsigned char
和signed char
的运算符<<
都是自由函数。这意味着在
大约<< (unsigned char) 255u
您的成员函数和采用unsigned char
的自由函数对于重载解析都是可见的。要调用采用
unsigned char
的自由函数,您的类实例必须绑定到对基类的引用,这算作“转换”,但右侧不需要转换。要调用成员函数,unsigned char
必须转换为bool
- 再次“转换”,但左侧不需要转换。这些转换序列都不比另一个更好,因此调用是不明确的。The
operator<<
instd::ostream
that are defined as member functions aren'tvirtual
. Youroperator<<
hides all of the base class versions of this function so they are not visible for overload resolution. However, theoperator<<
which are defined as free functions are visible.The
operator<<
which takechar
,unsigned char
andsigned char
are all free functions.This means that in
bout << (unsigned char) 255u
your member function and the free function taking anunsigned char
are both visible for overload resolution.To call the free function taking an
unsigned char
, your class instance has to be bound to a reference to a base class, and this counts as a 'Conversion' but the right hand side requires no conversion. To call your member function, theunsigned char
has to be converted to abool
- again a 'Conversion' but the left hand side requires no conversion. Neither of these conversion sequences is better than the other so the call is ambiguous.对于刚接触 iostream 的人来说,这是一个常见的错误,即派生新的流类型,因为您想以不同的方式输出数据。
您也不能添加自己的操作,即不能扩展 iomanip。
以不同格式输出数据的正确方法是对要输出的数据进行包装:
对于不同类型的 t.
然后,您可以将 my_formatter 作为仅返回 t 的模板函数,除非它已被专门化。您还可以给它多个参数。 (它将返回一个包含对基础数据的引用的类,并且将重载运算符<<)。
This is a common blunder for people who are new to iostreams, i.e. deriving a new stream type because you want to output the data in a different way.
You also cannot add your own manipulations, i.e. you cannot extend iomanip.
The correct way to output data in a different format is to put a wrapper around the data you wish to output:
for different types of t.
You can then have my_formatter as a template function that just returns t, unless it has been specialised. You can also give it multiple arguments. (It would return a class containing a reference to the underlying data, and would have operator<< overloaded).