0

I have the following macro definition:

#if DEBUG
#include <iostream>
#include <ostream>
#define LOG(x) std::cout << x << std::endl;
#else 
#define LOG(x) // LOG(x) is replaced with nothing in non-debug
#endif

How would an equivalent function look like that allows this?:

LOG("This is a Test message" << " with " << testVariable << " a variable");

my current implementation looks like this:

template <typename T>
inline void logD(const T& x) {
    if constexpr (Debug) {
        std::cout << x << std::endl;
    }
};

but I get the following error:

error C2296: '<<': illegal, left operand has type 'const char [25]'

replacing << with + for concatenating doesnt help either

 error C2110: '+': cannot add two pointers
Raildex
  • 3,406
  • 1
  • 18
  • 42
  • I suspect that even if the compiler inlines the function, the argument you pass will still take precedence and be evaluated first, as if it is wrapped in parentheses (which it is, really). Don't think there's a way to do this with a function. – Klaycon Jul 16 '20 at 19:12
  • Note you cannot get full equivalent to the macro - the biggest difference that arguments will be always evaluated for functions and not for macro, this could be significant difference for production code. – Slava Jul 16 '20 at 19:23
  • 1
    I'd probably just make a `std::ostream&` that in debug builds was `std::cout`, and in release builds was a [noop stream](https://stackoverflow.com/questions/11826554/standard-no-op-output-stream). – Mooing Duck Jul 16 '20 at 19:24
  • 1
    Alternatively, make the function into a vararg template, and pass each thing as a separate parameter, rather than having the caller merge them – Mooing Duck Jul 16 '20 at 19:26

2 Answers2

1

With the help of Mooing_Duck i made the function a vararg template and simply use the parameter pack.

template <typename ...T>
inline void logD(const T&... x) {
    if constexpr (DebugBuild) {
        (std::cout << ... << x) << std::endl;
    }
};

you call the function with separated commas for the content.

logD("This is a ","test with a ",variable," variable");
Raildex
  • 3,406
  • 1
  • 18
  • 42
0

The first part of function argument must be a well-defined type that can be used with standard streams, e.g:

std::string testVariable = "test";
LOG(std::string("This is a Test message") + " with " + testVariable + " a variable");
b00rt00s
  • 114
  • 5