0

如果想尽可能避免处理,在 C++ 中实现可打印类的正确方法是什么iostream

这个问题来自iostream,iosfwd与模板之间的交互。

1. 传统方法

据我所知,传统方法是:

我的类.hpp

#include<iostream>

template<class T>
class MyClass{
  ...

  friend std::ostream& operator<<(std::ostream& os, MyClass const& self){...; return os;}
};

然而,尽管某些类可以打印,例如用于调试,但并非所有用户都会对打印任何内容感兴趣。这些用户将(在编译时)为永远不会使用的东西付出代价。也就是包含和编译iostream.

(有,iosfwd但它对仅标题没有用。)

2. 模板operator<<

template<class T>
class MyClass{
  ...

  template<Ostream>
  friend Ostream& operator<<(Ostream& os, MyClass const& self){...; return os;}
};

这个我不必包含iostream在头文件中。它还存在operator<<可能返回非标准对象的问题,例如std::ofstream(而不是 base std::ostream)。

对打印感兴趣的用户必须包括iostream自己(并且在某种程度上知道这一点。)

缺点是Ostream可以搭配其他东西。可以将其与iosfwd约束Ostream(例如enable_if<is_base<std::ostream, Ostream>::value>)结合使用。不确定它是否有效。

3.单独MyClass/io.hpp的打印头

添加单独的文件

我的班级/io.hpp

  #include<iostream>

  template<class T>
  std::ostream& operator<<(std::ostream& os, MyClass<T> const& self){...; return os;}

在这种情况下,用户必须包含MyClass/io.hpp才能打印MyClass(并且知道这一点)。

此外,打印私有成员可能需要友谊,为此它需要<iosfwd>在 MyClass.h 中。

boost/units/io.hpp我在图书馆见过这个设计。

4.结合2和3

去完整的模板

我的班级/io.hpp

  template<class Ostream, class T>
  Ostream& operator<<(Ostream& os, MyClass<T> const& self){...; return os;}

std::iostream在使用模板和仅标头并iostream尽可能避免编译时,推荐的交互方式是什么?

总之,似乎使用单独的文件可以避免包含<iostream>. 模板和不需要友谊也可以避免iosfwd。受限制的模板或需要友谊的可能仍然需要iosfwd

4

0 回答 0