Q:

How to create functions like std::cout?

I'm creating my own logging utility for my project, I want to create a function like iostream's std::cout, to log to a file and print to the console as well.
Here's what i want:
enum
{
    debug, error, warning, info
};

LOG(level) << "test"; // level - from the above enum

The result should be like this:
int iPlayerID = 1337;
LOG(info) << "Player " << iPlayerID << "Connected";

[Thu Jan 29 18:32:11 2015] [info] Player 1337 Connected

A:

std::cout is not a function, it's an object of type std::ostream which overloads operator<<.
A quick sketch of how you could do it:
enum Level {
    debug, error, warning, info
};

struct Logger {
    std::ostream* stream;  // set this in a constructor to point
                           // either to a file or console stream
    Level debug_level;
public:
    Logger& operator<<(const std::string& msg)
    {
        *stream << msg; // also print the level etc.
        return *this;
    }

    friend Logger& log(Logger& logger, Level n);
    {
        logger.debug_level = n;
        return logger;
    }
};

Ant then use it like
Logger l;
log(l, debug) << "test";

A:

The trick is for your LOG(level) to return a special type which
contains a pointer to an std::ostream, and defines the << operator.
Something like:
class LogStream
{
    std::ostream* myDest;
public:
    LogStream( std::ostream* dest ) : myDest( dest ) {}

    template <typename T>
    LogStream& operator<<( T const& obj )
    {
        if ( myDest != nullptr ) {
            *myDest << obj;
        }
        return *this;
    }
};

The LOG(level) macro creats an instance of one, something like:
#define LOG(level) LogStream( getLogStream( level, __FILE__, __LINE__ ) )

Of course, the getLogStream may insert any information it wants (like a timestamp) at the moment it is called.
You might want to add a flush in the destructor of LogStream.

