如果想尽可能避免处理,在 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
。