forwarding Args&&... vs forwarding Args...

A

Andrew Tomazos

Can someone please clarify the difference (if any) between the
following two functions...

template<class... Args>
void f1(Args&&... args)
{
f(forward<Args>(args)...);
}

and

template<class... Args>
void f2(Args... args)
{
f(forward<Args>(args));
}

Thanks,
Andrew.
 
V

Victor Bazarov

Can someone please clarify the difference (if any) between the
following two functions...

template<class... Args>
void f1(Args&&... args)
{
f(forward<Args>(args)...);
}

and

template<class... Args>
void f2(Args... args)
{
f(forward<Args>(args));
}

Take it with a grain of salt, I don't know much about 'forward'
template. The '&&' notation designates an rvalue reference, so it
narrows down [a little bit] how types 'Args' are deduced, *I guess*.

V
 
V

Victor Bazarov

Can someone please clarify the difference (if any) between the
following two functions...

template<class... Args>
void f1(Args&&... args)
{
f(forward<Args>(args)...);
}

and

template<class... Args>
void f2(Args... args)
{
f(forward<Args>(args));
}

Take it with a grain of salt, I don't know much about 'forward'
template. The '&&' notation designates an rvalue reference, so it
narrows down [a little bit] how types 'Args' are deduced, *I guess*.

V
 
A

Andrew Tomazos

Can someone please clarify the difference (if any) between the
following two functions...

template<class... Args>
void f1(Args&&... args)
{
    f(forward<Args>(args)...);

}

and

template<class... Args>
void f2(Args... args)
{
    f(forward<Args>(args));

}

Errata: The second function should read:

template<class... Args>
void f2(Args... args)
{
    f(forward<Args>(args)...);

}

-Andrew.
 
M

Marc

Andrew said:
Can someone please clarify the difference (if any) between the
following two functions...

template<class... Args>
void f1(Args&&... args)
{
f(forward<Args>(args)...);
}

and

template<class... Args>
void f2(Args... args)
{
f(forward<Args>(args)...);
}

int i;
f1(i); // Args... is int& (and so is Args&&...)
f2(i); // Args... is int
so with f2 you copied the argument.
 
S

SG

Can someone please clarify the difference (if any) between the
following two functions...

template<class... Args>
void f1(Args&&... args)
{ f(forward<Args>(args)...); }

and

template<class... Args>
void f2(Args... args)
{ f(forward<Args>(args)); }

The difference (&&) affects template argument deduction. The first
function template always takes references as parameters and encodes
the value category of the supplied arguments as part of the type
parameters. This value category is then restored by std::forward. The
second function template always takes function parameters by value and
the forward call is basically just a move request (like std::move).

Keep in mind that something like

template<class T>
void foo(T&& x);

is basically a "catch everything and remember the value category, too,
so that it can be restored later"-signature.

int main() {
int i = 23;
// special deduction rule for T&& with lvalue arguments
// |
// | reference collapsing
// | |
foo(i); // --> deduce T=int& --> T&&=int&
foo(i+0); // --> deduce T=int --> T&&=int&&
}

As for restoring the value category:
forward<int >(...) yields an rvalue.
forward<int&>(...) yields an lvalue.

The use of std::forward is necessary because named rvalue references
are actually lvalues. The x in foo above is ALWAYS lvalue.

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top