我有一个价值语义课,我想成为"可展示的"与Haskells Show
类的意义相同,或者Python提供了通用的__str__()
函数。
在c ++中:
operator<<(ostream&, ...)
,因此我可以将我的课程输出到例如cout
operator std::string()
所以我的类转换为 std :: string operator const char*()
,以便我的类转换为 const char *。str()
成员,或to_string(...)
免费功能这些功能中的每一个都可以用另一个来定义。一个选项比其他选项更好吗?这些都是选择吗?在c ++ 11/14/17中,最优雅的方法是什么?
答案 0 :(得分:8)
这个问题将在几分钟内搁置,但我仍然会在这里分享我的想法。
首先,我们可以从列表中删除const char * / std :: string()运算符重载。如果类不是字符串,则它不应该可转换为字符串,并且序列化启用不会使您的类成为字符串。
对于str()
,to_string
和operator <<
,它们非常相同。但是,因为对于任何复杂的类,to_string()和str()很可能在内部使用ostreams,我相信,operator <<
是最好的选择。
答案 1 :(得分:2)
我不知道这是否是最佳做法,但......
用于调试我总是定义operator<<
,它以文本形式提供汇总输出(这意味着可以很容易地将对象流式传输到日志文件)
对于格式化输出我可能会选择在自由函数方面实现这一点:detail::x_detail_writer write_details(const X&)
然后给detail::x_detail_writer
(这是一个仿函数)operator<< overload
除了to_string
以operator<<
表示最简单的对象外,其他任何事情都是如此。
为了帮助调试输出,我们有一个辅助类,如下所示:
template<class T>
struct make_writeable {
friend std::ostream& operator<<(std::ostream& os, const T& t) {
// example prefix...
os << demangle(typeid(T).name()) << "{";
t.write(os);
// example postfix:
os << " }";
return os;
}
};
然后从中派生出一些类,并给它一个名为write的成员函数:
struct X : make_writeable<X>
{
void write(std::ostream& os) const {
// write out members here. they will appear within the prefix and postfix
}
};