Paulo Matos
Paulo Matos

Reputation: 1664

C++ template specialization for POD types in logger library

I am rolling my own logging library. The idea is to have an interface class which must be derived from so that an object is able to be logged from.

class LoggedType
{
 public:
  virtual std::ostream &log (std::ostream &) const = 0;
};

Then the Log class will implement operator<< and for LoggedType use the log method. For everything else will use the normal operator<<.:

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;
 }
};

I am getting errors as LoggedType classes are also being matched to the templated operator<<, when only non LoggedType classes should use that template.

How to best fix this?

Upvotes: 0

Views: 175

Answers (1)

Jarod42
Jarod42

Reputation: 217930

You may change your template function to use SFINAE:

template <typename T>
friend
typename std::enable_if<!std::is_base_of<LoggedType, T>::value, Log &>::type
operator<< (Log &l, const T &t);

Upvotes: 1

Related Questions