'C++ unpack variadic template arguments with the next function returns nothing [duplicate]

I'm trying to expand arguments to a variadic function. Code below works perfectly fine

template<typename T>
int printMy (const T& f)
{
    cout << f << endl;
}
template<typename... Types>
void print (Types... args)
{
    auto i = {printMy(args)...};
}

int main() {
    std::string s("world");
    print(7.5, "hello", s);
    return 0;
}

However, I don't really want to return anything from the function. I actually want it to be void. However, when I have code like below, it doesn't work

template<typename T>
void printMy (const T& f)
{
    cout << f << endl;
}
template<typename... Types>
void print (Types... args)
{
    {printMy(args)...};
    // same thing if I remove the brackets
    // printMy(args)...;
}

It gives me an error on the line "{printMy(args)...};". The error is "Expression contains unexpanded parameter pack 'args'"



Solution 1:[1]

You can use fold expression with C++17 to compute the result of using a binary operator over all the arguments of the parameter pack, to solve the problem as shown below. The shown program uses unary right fold to achieve the desired effect.

template<typename... Types>
void print (Types... args)
{
  
    (printMy(args), ...);//uses fold expression in C++17
}

Demo

Solution 2:[2]

Since C++17, you might use

template<typename... Types>
void print (Types... args)
{
    (printMy(args), ...);
}

Before that, you have to use trick similar to what you did:

template<typename... Types>
void print (Types... args)
{
    const int dummy[] = {0, (printMy(args), 0)...};
    static_cast<void>(dummy); // Avoid warning for unused variable
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anoop Rana
Solution 2 Jarod42