I'm trying to create a simple logger which logs different messages to disk. The logger is a simple class of which I've overridden the << operator and, in order to save the messages, I send an enum value signaling to save what has come so far. basically flush everything to the disk.
This is how I intend on using this logger:
Logging::Logger << "First " << 255 << "Second" << exc.what() << Logging::Save; As you can see, since I need a way to distinuish between controling arguments such as Logging::Save and other normal arguments, I need to know what I'm dealing with. For getting the type of argument sent, I used std::is_same. However, it seems for some reasons the check doesn't work and I get the following error :
In instantiation of 'Logging::Log& Logging::Log::operator<<(const T&) [with T = char [19]]': 104:35: required from here 47:31: error: no match for 'operator==' (operand types are 'const char [19]' and 'Logging::Mode') In instantiation of 'Logging::Log& Logging::Log::operator<<(const T&) [with T = Logging::Mode]': 104:67: required from here 57:28: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&' In file included from /usr/include/c++/4.9/iostream:39:0, from 10: /usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Logging::Mode]' operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) ^ This is what I have come up so far :
#include <iostream> #include <fstream> #include <sstream> #include <typeinfo> #include <type_traits> namespace Logging { enum class Mode { Save = 0, Load = 1 }; static constexpr Mode Save = Mode::Save; class Log { private: std::stringstream stream; bool isNew = true; bool displayResults = false; public: template <typename T> Log& operator<<(const T& value) { if (isNew) { stream << "start : "; isNew = false; } if (std::is_same<T, Logging::Mode>::value) { if (value == Mode::Save) Save(); if (displayResults) std::cout << std::endl; isNew = true; } else { stream << value; } if (displayResults) std::cout << stream.str(); return *this; } void Save(std::string logFilename= "Log.txt") { isNew = true; std::ofstream logFile; logFilename = (logFilename == "") ? "Log.txt" : logFilename; logFile.open(logFilename, std::ios::out | std::ios::app); logFile << this->Get(); this->stream.clear(); this->stream.str(""); } Log& Display(bool status) { displayResults = status; return *this; } std::string Get() const { return this->stream.str(); } friend std::ostream& operator<<(std::ostream& os, const Log& log); }; std::ostream& operator<<(std::ostream& os, const Log& log) { os << log.Get(); return os; } Log Logger; } int main() { Logging::Logger.Display(true)<< "What is your name?" <<Logging::Save; } What am I missing here?
operator<<for aLogging::Modeargument?