5

I like how easy it is to write some variables to console output in C++ using qDebug from Qt:

int a = b = c = d = e = f = g = 1;
qDebug() << a << b << c << d << e << f << g;

Result:

1 1 1 1 1 1 1

In comparison, using std::cout would require me to add the spacing and newline manually to get the same result:

std::cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << " " << g << "\n";

While I often use Qt, I sometimes work on projects where adding the Qt framework just to get access to qDebug would be overkill. And although it is not hard to write a new class that behaves similar to qDebug, I am wondering if any established alternative to std::cout with similar behavior to qDebug already exists?

Edit: What I am looking for is ideally an established library (or snippet, but I prefer something existing over rolling my own) that I can always use as my go-to solution when I need something like this. It could be header-only, or a large logging library that is much used and well-tested, or a simple, small snippet. The point is that it should be small and/or standard enough that other collaborators would be okay with including it in a project just for debugging/logging purposes.

Edit 2: To clarify: It would be great to have a solution that both inserts spaces between the variables and newlines for each statement:

myDebug << 1 << 2 << 3;
myDebug << 4 << 5 << 6;

Should return:

1 2 3
4 5 6
dragly
  • 1,445
  • 11
  • 14
  • 1
    No in C++ built-in, AFAIK. – user202729 Mar 20 '18 at 10:33
  • I'll update the question to make it more clear, but what I am looking for is ideally a library (or snippet) that I can always use as my go-to solution when I need something like this. It could be header-only, or a large logging library that is much used and well-tested. It can also be a small snippet. The point is that it should be small and/or standard enough that other collaborators would be okay with including it in a project just for debugging/logging purposes. This might be close enough to be a duplicate, though. – dragly Mar 20 '18 at 10:58

2 Answers2

7
struct debugcout { };

template <typename T>
debugcout& operator<<(debugcout& os, const T& x)
{
    std::cout << x << ' ';
    return os;
}

inline debugcout debug{};

Usage:

int main()
{
    debug << 1 << 2 << 3;
}
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • Thanks! This is close to what I want, but it is missing automatic newline insertion. That might be harder to implement in only a few lines, but I might be wrong. Also, the inline variable does not seem to compile with GCC 5.4, even with C++1z/C++17 specified. – dragly Mar 20 '18 at 11:05
  • 3
    @dragly It's a C++17 feature named *inline variable* [supported since GCC 7](http://en.cppreference.com/w/cpp/compiler_support). – O'Neil Mar 20 '18 at 11:34
3
#include <iostream>

class myDebug {
    bool is_first{true};
    bool is_last{true};
public:
    myDebug() = default;
    myDebug(myDebug const &) = delete;
    myDebug & operator = (myDebug const &) = delete;
    myDebug & operator = (myDebug &&) = delete;
    myDebug(myDebug && dc) noexcept 
      : is_first{false} {
        dc.is_last = false;
    }
    ~myDebug() {
        if (is_last)
            std::cout << '\n';
    }
    template <typename T>
    friend myDebug operator<<(myDebug db, const T& x) {
        if (db.is_first)
            db.is_first = false;
        else
            std::cout << ' ';

        std::cout << x;
        return db;
    }
};
int main() {
    myDebug() << 1 << 2 << 3;
    myDebug() << 4 << 5 << 6;
}

Demo

O'Neil
  • 3,790
  • 4
  • 16
  • 30