Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a variadic macro for std::cout?

How would I make a macro that took a variable amount of arguments, and prints its out using std::cout? Sorry if this is a noob question, couldn't find anything that clarified variadic macros after searching around for the answer.

Conceptual Example:

#include <iostream>
#define LOG(...) std::cout << ... << ... << std::endl
int main() {
    LOG("example","output","filler","text");
    return 0;
}

would output:

exampleoutputfillertext
like image 758
BlurryZombie Avatar asked Mar 29 '15 06:03

BlurryZombie


People also ask

How do I use variadic macros?

To use variadic macros, the ellipsis may be specified as the final formal argument in a macro definition, and the replacement identifier __VA_ARGS__ may be used in the definition to insert the extra arguments. __VA_ARGS__ is replaced by all of the arguments that match the ellipsis, including commas between them.

What is __ Va_args __ C++?

macro expansion possible specifying __VA_ARGS__ The '...' in the parameter list represents the variadic data when the macro is invoked and the __VA_ARGS__ in the expansion represents the variadic data in the expansion of the macro. Variadic data is of the form of 1 or more preprocessor tokens separated by commas.

What is ## in C macro?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is __ Va_opt __?

__VA_OPT__ is a new feature of variadic macros in C++20. It lets you optionally insert tokens depending on if a variadic macro is invoked with additional arguments. An example usage is comma elision in a standardized manner.


1 Answers

You do not need preprocessor macros to do this. You can write it in ordinary C++. In C++11/14:

#include <iostream>
#include <utility>

void log(){}

template<typename First, typename ...Rest>
void log(First && first, Rest && ...rest)
{
    std::cout << std::forward<First>(first);
    log(std::forward<Rest>(rest)...);
}

int main()
{
    log("Hello", "brave","new","world!\n");
    log("1", 2,std::string("3"),4.0,'\n');
}

Live demo

In C++17:

template<typename ...Args>
void log(Args && ...args)
{
    (std::cout << ... << args);
}

is all it takes. Live demo

Output:

Hellobravenewworld!
1234

Research variadic templates, parameter packs and fold expressions rather than variadic macros, which are rarely useful in modern C++.

like image 135
Mike Kinghan Avatar answered Sep 22 '22 11:09

Mike Kinghan