Sök…


Anmärkningar

Perfekt vidarebefordran kräver vidarebefordran av referenser för att bevara ref-kvalificeringen av argumenten. Sådana referenser förekommer endast i ett deducerat sammanhang . Det är:

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
}

Följande innebär inte perfekt vidarebefordran, eftersom T inte dras från konstruktörens samtal:

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

C ++ 17 tillåter avdrag för klassmallargument. Konstruktören av "a" i exemplet ovan kommer att bli en användare av en vidarebefordringsreferens

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

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

Fabriksfunktioner

Anta att vi vill skriva en fabriksfunktion som accepterar en godtycklig lista med argument och överför dessa argument omodifierade till en annan funktion. Ett exempel på en sådan funktion är make_unique , som används för att säkert konstruera en ny instans av T och returnera en unique_ptr<T> som äger instansen.

Språkreglerna för variadiska mallar och värderingsreferenser gör det möjligt för oss att skriva en sådan funktion.

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

Användningen av ellipser ... indikerar ett parameterpaket som representerar ett godtyckligt antal typer. Kompilatorn utvidgar detta parameterpaket till rätt antal argument på samtalssidan. Dessa argument överförs sedan till T : s konstruktör med std::forward . Denna funktion krävs för att bevara ref-kvalificeringen av argumenten.

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow