Buscar..


Observaciones

El reenvío perfecto requiere reenviar las referencias para preservar los ref-calificadores de los argumentos. Tales referencias aparecen solo en un contexto deducido . Es decir:

template<class T>
void f(T&& x) // x is a forwarding reference, because T is deduced from a call to f()
{
    g(std::forward<T>(x)); // g() will receive an lvalue or an rvalue, depending on x
}

Lo siguiente no implica un reenvío perfecto, porque T no se deduce de la llamada del constructor:

template<class T>
struct a
{
    a(T&& x); // x is a rvalue reference, not a forwarding reference
};
C ++ 17

C ++ 17 permitirá la deducción de argumentos de plantilla de clase. El constructor de "a" en el ejemplo anterior se convertirá en un usuario de una referencia de reenvío

a example1(1);
  // same as a<int> example1(1);

int x = 1;
a example2(x);
  // same as a<int&> example2(x);

Funciones de fábrica

Supongamos que queremos escribir una función de fábrica que acepte una lista arbitraria de argumentos y pase esos argumentos sin modificar a otra función. Un ejemplo de una función de este tipo es make_unique , que se utiliza para construir de forma segura una nueva instancia de T y devolver un unique_ptr<T> que posee la instancia.

Las reglas de lenguaje con respecto a las plantillas variadas y las referencias de valores nos permiten escribir dicha función.

template<class T, class... A>
unique_ptr<T> make_unique(A&&... args)
{
    return unique_ptr<T>(new T(std::forward<A>(args)...));
}

El uso de puntos suspensivos ... indica un paquete de parámetros, que representa un número arbitrario de tipos. El compilador expandirá este paquete de parámetros al número correcto de argumentos en el sitio de la llamada. Estos argumentos luego se pasan al constructor de T usando std::forward . Esta función es necesaria para conservar los ref-calificadores de los argumentos.

struct foo
{
    foo() {}
    foo(const foo&) {}                    // copy constructor
    foo(foo&&) {}                         // copy constructor
    foo(int, int, int) {}
};

foo f;
auto p1 = make_unique<foo>(f);            // calls foo::foo(const foo&)
auto p2 = make_unique<foo>(std::move(f)); // calls foo::foo(foo&&)
auto p3 = make_unique<foo>(1, 2, 3); 


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow