C ++重载了运算符解析

时间:2010-11-12 06:58:03

标签: c++ overloading iostream resolution operator-keyword

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);
}

它基本上允许你将单个位写为bool然后它将使用父&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;方法。我不得不在这里使用这个调用语法,因为我在调用基本方法,但是在我使用这个类的实际main方法中,我尝试调用以下行:

bout << (unsigned char) 255u;

我想调用&lt;&lt;已经为ofstream和unsigned char定义的方法,但是它给了我一个长的模糊重载错误,列出了已经为ofstream定义的所有char相关候选项(char,unsigned char,signed char)和我自己的bool方法,即使我明确地转换为char。但是我确实设法使用以下内容:

bout.operator<<((unsigned char) 255u);

这必须与g ++如何进行隐式转换有关(我的猜测是在第一种情况下我的用户定义的强制转换之后还有一次可能的强制转换,这使得函数调用语法避免不明确)。有没有人确切知道为什么会发生这种情况,或者是否有更好的语法来避免错误?

2 个答案:

答案 0 :(得分:5)

operator<<中定义为成员函数的std::ostream不是virtual。您的operator<<隐藏了此函数的所有基类版本,因此它们在重载解析时不可见。但是,定义为自由函数的operator<<是可见的。

operator<<charunsigned char signed char都是免费功能。

这意味着在bout << (unsigned char) 255u中,您的成员函数和使用unsigned char的自由函数都可以用于重载解析。

要调用带有unsigned char的自由函数,您的类实例必须绑定到对基类的引用,这将被视为“转换”,但右侧不需要转换。要调用您的会员功能,unsigned char必须转换为bool - 再次转换为'转化',但左侧不需要转换。这些转换序列都没有比另一个好,所以调用不明确。

答案 1 :(得分:2)

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

您也无法添加自己的操作,即无法扩展iomanip。

以不同格式输出数据的正确方法是在您希望输出的数据周围放置一个包装器:

ostream& os << my_formatter(t);

针对不同类型的t。

然后你可以将my_formatter作为模板函数返回t,除非它已被专门化。你也可以给它多个参数。 (它将返回一个包含对基础数据的引用的类,并且将具有运算符&lt;&lt; overloaded)。