Zoeken…


Opmerkingen

Perfect forwarding vereist forwarding referenties om de ref-kwalificaties van de argumenten te behouden. Dergelijke verwijzingen verschijnen alleen in een afgeleide context . Dat is:

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
}

Het volgende houdt geen perfect doorsturen in, omdat T niet is afgeleid van de constructor-aanroep:

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

Met C ++ 17 kunnen argumenten van klassesjablonen worden afgeleid. De constructor van "a" in het bovenstaande voorbeeld wordt een gebruiker van een doorstuurreferentie

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

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

Fabrieksfuncties

Stel dat we een fabrieksfunctie willen schrijven die een willekeurige lijst met argumenten accepteert en die argumenten ongewijzigd doorgeeft aan een andere functie. Een voorbeeld van een dergelijke functie is make_unique , die wordt gebruikt om veilig een nieuwe instantie van T te construeren en een unique_ptr<T> die eigenaar is van de instantie.

De taalregels met betrekking tot variadische sjablonen en waardeverwijzingen stellen ons in staat om een dergelijke functie te schrijven.

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

Het gebruik van ellipsen ... geeft een parameterpakket aan, dat een willekeurig aantal typen vertegenwoordigt. De compiler zal dit parameterpakket uitbreiden naar het juiste aantal argumenten op de aanroepsite. Deze argumenten worden vervolgens doorgegeven aan de constructor van T met std::forward . Deze functie is vereist om de ref-kwalificaties van de argumenten te behouden.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow