C++重载运算符解析

发布于 2024-10-01 17:44:44 字数 890 浏览 6 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

櫻之舞 2024-10-08 17:44:44

std::ostream 中定义为成员函数的运算符<< 不是虚拟。您的运算符<<隐藏此函数的所有基类版本,因此它们对于重载解析不可见。然而,定义为自由函数的运算符<<是可见的。

采用 charunsigned charsigned char运算符<<都是自由函数。

这意味着在大约<< (unsigned char) 255u 您的成员函数和采用 unsigned char 的自由函数对于重载解析都是可见的。

要调用采用 unsigned char 的自由函数,您的类实例必须绑定到对基类的引用,这算作“转换”,但右侧不需要转换。要调用成员函数,unsigned char 必须转换为 bool - 再次“转换”,但左侧不需要转换。这些转换序列都不比另一个更好,因此调用是不明确的。

The operator<< in std::ostream that are defined as member functions aren't virtual. Your operator<< hides all of the base class versions of this function so they are not visible for overload resolution. However, the operator<< which are defined as free functions are visible.

The operator<< which take char, unsigned char and signed char are all free functions.

This means that in bout << (unsigned char) 255u your member function and the free function taking an unsigned 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, the unsigned char has to be converted to a bool - 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.

纵性 2024-10-08 17:44:44

对于刚接触 iostream 的人来说,这是一个常见的错误,即派生新的流类型,因为您想以不同的方式输出数据。

您也不能添加自己的操作,即不能扩展 iomanip。

以不同格式输出数据的正确方法是对要输出的数据进行包装:

ostream& os << my_formatter(t);

对于不同类型的 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:

ostream& os << my_formatter(t);

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文