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) 定义的所有与 char 相关的候选对象和我自己的 bool 方法,即使我明确地转换为 char。但是我确实设法让它与以下内容一起工作:

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

这一定与 g++ 如何进行隐式转换有关(我的猜测是在第一种情况下我的用户定义转换之后还有一个可能的转换,这使得函数调用语法避免了模棱两可)。有谁知道为什么会发生这种情况,或者是否有更好的语法可以避免错误?

4

2 回答 2

5

被定义为成员函数的operator<<instd::ostream不是virtual. 您operator<<隐藏了此函数的所有基类版本,因此它们对于重载决议不可见。但是,operator<<定义为自由函数的那些是可见的。

其中operator<<,char和都是自由函数unsigned charsigned char

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

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

于 2010-11-12T07:44:30.283 回答
2

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

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

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

ostream& os << my_formatter(t);

对于不同类型的 t。

然后,您可以将 my_formatter 作为仅返回 t 的模板函数,除非它已被专门化。你也可以给它多个参数。(它将返回一个包含对基础数据的引用的类,并且操作符<< 被重载)。

于 2010-11-12T08:37:34.420 回答