我正在滚动自己的日志库。 我们的想法是拥有一个必须从中派生的接口类,以便能够从中记录对象。
class LoggedType
{
public:
virtual std::ostream &log (std::ostream &) const = 0;
};
然后Log类将实现运算符<<对于LoggedType,使用log方法。其他一切将使用普通运算符<<。:
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
typedef CoutType &(*StandardEndLine)(CoutType&);
class Log
{
public:
Log (std::ostream &);
Log (const std::string &);
~Log ();
private:
std::ostream *os;
bool file_p;
friend Log &operator<< (Log &l, const LoggedType &t)
{
t.log (*l.os);
return l;
}
template <typename T>
friend Log &operator<< (Log &l, const T &t)
{
*l.os << t;
return l;
}
friend Log &operator<< (Log &log, StandardEndLine manip)
{
manip (*(log.os));
return log;
}
};
我收到错误,因为当只有非LoggedType类应该使用该模板时,LoggedType类也与模板化运算符&lt;&lt;匹配。
如何最好地解决这个问题?
答案 0 :(得分:1)
您可以更改模板功能以使用SFINAE:
template <typename T>
friend
typename std::enable_if<!std::is_base_of<LoggedType, T>::value, Log &>::type
operator<< (Log &l, const T &t);