C++
Idealne przekazywanie
Szukaj…
Uwagi
Idealne przekazywanie wymaga przekazywania referencji , aby zachować kwalifikatory ref argumentów. Takie odniesienia pojawiają się tylko w przewidywanym kontekście . To jest:
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
}
Poniższe nie obejmuje doskonałego przekazywania, ponieważ T
nie jest wywnioskowane z wywołania konstruktora:
template<class T>
struct a
{
a(T&& x); // x is a rvalue reference, not a forwarding reference
};
C ++ 17 pozwoli na odjęcie argumentów szablonu klasy. Konstruktor „a” w powyższym przykładzie stanie się użytkownikiem odwołania do przekazywania
a example1(1);
// same as a<int> example1(1);
int x = 1;
a example2(x);
// same as a<int&> example2(x);
Funkcje fabryczne
Załóżmy, że chcemy napisać funkcję fabryczną, która akceptuje dowolną listę argumentów i przekazuje te argumenty w postaci niezmodyfikowanej do innej funkcji. Przykładem takiej funkcji jest make_unique
, która jest używana do bezpiecznego skonstruowania nowej instancji T
i zwrócenia unique_ptr<T>
która jest właścicielem instancji.
Reguły językowe dotyczące różnych szablonów i odniesień do wartości pozwalają nam napisać taką funkcję.
template<class T, class... A>
unique_ptr<T> make_unique(A&&... args)
{
return unique_ptr<T>(new T(std::forward<A>(args)...));
}
Zastosowanie elips ...
wskazuje pakiet parametrów, który reprezentuje dowolną liczbę typów. Kompilator rozszerzy ten pakiet parametrów do poprawnej liczby argumentów w witrynie wywoływania. Te argumenty są następnie przekazywane do konstruktora T
za pomocą std::forward
. Ta funkcja jest wymagana do zachowania kwalifikatorów ref argumentów.
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);