I understand that a forwarding reference is "an rvalue reference to a cv-unqualified template parameter", such as in
template <class T> void foo(T&& );
which means the above function can take both l-value and r-value reference.
There's something I don't understand, e.g.
template <class T>
class A
{
template <class U>
void foo(T&& t, U&& u)
{
T t2( std::forward(t) ); // or should it be std::move(t)? is T&& forwarding or r-value reference
U u2( std::forward(u) ); // or should it be std::move(u)? I believe U&& is forwarding reference
}
};
in the above code, are both T&& and U&& forwarding references?
I wrote some code to test (VS2015 compiler):
class A
{
public:
A(){};
A(const A& rhs)
{
std::cout << "calling 'const A&' l-value" << std::endl;
}
A(A&& rhs)
{
std::cout << "calling ' A&&' r-value" << std::endl;
}
};
template <class T>
class Test
{
public:
void test1(T&& t)
{
T t2(std::forward<T>(t));
}
template <typename X>
void test2(X&& x)
{
T t2( std::forward<T>( x ) );
}
};
void main()
{
A a;
Test<A> test;
test.test1(A());
test.test1(std::move(a));
//test.test1(a); // this doesn't compile. error: cannot convert argument 1 from 'A' to 'A &&', You cannot bind an lvalue to an rvalue reference
test.test2<A>(A());
test.test2<A>( std::move( a ) );
//test.test2<A>( a ); // this doesn't compile. error: cannot convert argument 1 from 'A' to 'A &&', You cannot bind an lvalue to an rvalue reference
}
I was expecting that test.test1(a) and test.test2<A>(a) should both compile if they are forwarding references, but neither does.
Could someone explain this to me?
It's a great question which foxes almost everyone in the beginning.
In this example,
Tis not deduced (you explicitly define it when you instanciate the template).Uis deduced because it's deduced from the argumentu.Therefore, in almost all cases it would be: