Entiendo que una referencia de reenvío es “una referencia de valor real a un parámetro de plantilla no calificado de cv”, como en
template <class T> void foo(T&& );
lo que significa que la función anterior puede tomar como referencia tanto el valor l como el valor r.
Hay algo que no entiendo, por ejemplo
template <class T>
class A
{
template <class U>
void foo(T&& t, U&& u)
{
T t2( std::forward
U u2( std::forward(u) ); // or should it be std::move(u)? I believe U&& is forwarding reference
}
};
en el código anterior, ¿Son T&& y U&& referencias de reenvío?
Escribí un código para probar (compilador VS2015):
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>
}
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
}
Esperaba que test.test1(a); y test.test2(a) deberían compilarse si están reenviando referencias, pero ninguno lo hace.
¿Podría alguien explicarme esto? ¡Gracias!
Editar
————–gracias, muchachos———– Richard y Artemy tienen razón.
Sin relación, no sé si es triste o surrealista que, hoy en día, la cadena de herramientas VS2015 acepte
void main()
. En serio ?– WhozCraig
1 de septiembre de 2017 a las 8:50
En su último caso cerrado, U no se deduce, por lo que su caso no se compilará. Para hacerlo deducible, llámelo test.test2( a ); y dentro de la prueba 2 cambia adelante a adelante
– Artemy Vysotsky
1 de septiembre de 2017 a las 9:05