I came across this function below written in C++. A call to the function trace() with any number of arguments prints the values of each of these arguments alongside the name of the argument in the format
name1 : value1 | name2 : value2 and so on.
I wanted to learn how this code is working and what some of the syntax like the double ampersand &&, __VA_ARGS__ meant. Thanks!
#define tr(...) trace(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void trace(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void trace(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');
    cout.write(names, comma-names) << " : " << arg1 << " | " ; 
    trace(comma+1, args...);
}
 
     
     
    