areuz areuz - 3 months ago 13
C++ Question

Processing all passed overloads at once

I'm tired of making up on the spot debug codes and including

<iostream>
in every single file. So I wanted to make myself a universal, self-contained and lightweight debug class, that I would just include in the header, and forget.

I want to use something along the lines of

#include "debug.hpp"
debug DBG;
DBG << "foo and" << " bar";
//Or even better, just include it and do debug() << "foo and" << " bar";


So, I wrote this:

#include <iostream>
#include <string>
#include <chrono>
#include <ctime>

class Debug
{
public:
Debug &operator<<(std::string arg_0)
{
auto tempTime = std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now() );
auto timeString(ctime(&tempTime));
timeString = timeString.substr(timeString.find(':') - 2, 8);

std::cout << timeString << " >> " << arg_0 << '\n';
return *this;
}
};


But of course, this doesn't work because, as I've learned, every overload operator causes this function (is it still called a function?) to trigger separately. Creating:

hour:minute:second >> foo and
hour:minute:second >> bar


Any way I could pass everything at once after the first overload operator appears? Maybe as a stringstream? Also, I won't be only passing strings, but anything that I need, will this require me to manually create a separate overload function for every signle type that I may pass?

P.S: Cross-plaform solution is optional, but welcome (Currently developing on Linux)

Answer

You may return an other class to do the job, something like:

class Helper
{
public:
    ~Helper() { std::cout << "\n"; }

    template<typename T>
    friend Helper&& operator << (Helper&&h, const T& t) {
        std::cout << t;
        return std::move(h);
    }
};

class Debug
{
public:    
  template<typename T>
  friend Helper operator<<(Debug&, const T& t)
  {
    auto tempTime = std::chrono::system_clock::to_time_t(
      std::chrono::system_clock::now() );
    auto timeString{ctime(&tempTime)};
    timeString = timeString.substr(timeString.find(':') - 2, 8);

    std::cout << timeString << " >> " << t;
    return Helper{};
  }
};