我想将类实例的文本描述放在ostream中,如
ostream << myInstance;
我知道如何声明一个ostream插件;
ostream& operator<<(ostream&, myClass&);
我希望能够为ostream添加不同级别的细节。如果我可以定义两个或更多的ostream插入器,或者将一个额外的参数传递给插入器,或者将一个方法传递给插入器,或者调用一个返回字符串流的方法(我可以这样做吗?)
有没有人解决过这个问题?
答案 0 :(得分:2)
您可以通过实际包含流本身来将“标记”添加到流中。
struct Verbose {
explicit Verbose(std::ostream* s = 0): _stream(s) {}
std::ostream* _stream;
};
Verbose operator<<(std::ostream& out, Verbose) {
return Verbose(&out);
}
然后,为详细输出定义一个新运算符:
std::ostream& operator<<(Verbose v, MyClass const& mc) {
assert(v._stream);
std::ostream& out = *v._stream;
// ...
return out;
}
用法:
std::cout << Verbose() << myInstance << "\n";
你会注意到Verbose
与课程没有关联,并且可以很容易地在课程中重复使用。
注意:如果您愿意,可以在Verbose
添加一个额外的参数,以直接在那里实际控制详细程度。
答案 1 :(得分:2)
标准解决方案是使用标志或定义自定义操纵器
存储在ios::xalloc
提供的数据中的其他格式信息。
类似的东西:
int
flagIndex()
{
static int const theIndex = std::ostream::xalloc();
return theIndex;
}
std::ostream&
verbose( std::ostream& stream )
{
stream.iword( flagIndex() ) = 1;
return stream;
}
std::ostream&
unverbose( std::ostream& stream )
{
stream.iword( flagIndex() ) = 0;
return stream;
}
std::ostream&
operator<<( std::ostream& dest, MyClass const& object )
{
bool verbose = dest.iword( flagIndex() ) != 0;
// ...
return dest;
}
然后您可以编写如下内容:
std::cerr << verbose << myObject;
答案 2 :(得分:1)
您无法向operator<<
添加额外参数,但您可以使用详细程度参数轻松定义自定义打印功能:
void dump(ostream& ostr, const myClass& obj, int verbosity = 1)
{
if (verbosity > 2)
ostr << "Very verbose!\n";
if (verbosity > 1)
ostr << "Verbose!\n";
if (verbosity > 0)
ostr << "Standard!\n";
ostr << "Minimal.\n";
}
用法:
dump(cout, myobj); // Default
dump(cout, myobj, 0); // Minimal
dump(cout, myobj, 1); // Default
dump(cout, myobj, 2); // Verbose
dump(cout, myobj, 3); // Very verbose
您还应该使用默认的详细程度
提供转发到dump()
的流操作员
ostream& operator<<(ostream& ostr, const myClass& obj)
{
dump(ostr, obj);
return ostr;
}
如果您想遵循这种方式,最好为详细程度声明enum
而不是使用int
s:
enum Verbosity
{
MinimalOutput = 0,
StandardOutput = 1,
VerboseOutput = 2,
DebugOutput = 3
};
答案 3 :(得分:0)
修改项目格式的标准方法是实现操纵器。它通常只会设置一些标志。然后,您的插入器将根据标志的状态修改其行为。