How to perfect forward the elements of a function parameter pack in C++
Asked Answered
C

1

7

I am having trouble understanding how to forward the elements of a parameter pack in C++. Please take for example the code below:

#include <iostream>

void print(const int& value) {
    std::cout << "print(const int& value) - " << value << std::endl;
}

void print(int&& value) {
    std::cout << "print(int&& value) - " << value << std::endl;
}

template <class... Arg>
void print_each_argument(Arg&&... args) {
    for(auto&& a: { args... }) {
        print(std::forward<decltype(a)>(a));
    }
}

int main() {
    int some_value = 10;
    int other_value = 20;
    print_each_argument(some_value, other_value, 12, 14);

    return 0;
}

Output:

print(const int& value) - 10
print(const int& value) - 20
print(const int& value) - 12
print(const int& value) - 14

What I expected to see was the following output:

Output:

print(const int& value) - 10
print(const int& value) - 20
print(int&& value) - 12
print(int&& value) - 14

Can someone explain on why the behavior is the one that it is?

I tried to compile the code and check the result.

Cofield answered 2/5, 2023 at 13:52 Comment(2)
int some_value = 10; => you create a int not a reference to a int. Maybe try: int some_value = 10; int& ref_to_some_value = some_value;Allergic
Given that initializer list elements are const, I'm surprised that you found a compiler that will compile this code. Is this the real code that's producing the output you show?Ambages
T
11

You loose the ability to forward as soon as you do { args... } as that creates a std::initializer_list which copies all of the elements into a underlying temporary array of const objects.

Instead you can use a fold expression to call print on each member of the paramter pack like

template <class... Arg>
void print_each_argument(Arg&&... args) {
    (print(std::forward<Arg>(args)), ...);
}
Tropaeolin answered 2/5, 2023 at 13:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.