std::reference_wrapper
şablonlarla birlikte kullanışlıdır. Bir nesneyi üzerine bir işaretçi depolayarak sararak, olağan semantiğini taklit ederken yeniden atama ve kopyalamaya izin verir. Ayrıca, belirli kütüphane şablonlarına nesneler yerine referansları saklamalarını söyler.
STL'deki functor'ları kopyalayan algoritmaları düşünün: Functor'un kendisi yerine functor'a atıfta bulunan bir referans sarmalayıcıyı ileterek bu kopyayı önleyebilirsiniz:
unsigned arr[10];
std::mt19937 myEngine;
std::generate_n( arr, 10, std::ref(myEngine) );
Bu işe yarıyor çünkü…
... reference_wrapper
s aşırı yükoperator()
onlar sadece işlev gibi çağrılabilir yüzden bakın nesneleri:
std::ref(myEngine)()
… (Un) sıradan referanslar gibi, kopyalama (ve atama) reference_wrappers
sadece pointee atar.
int i, j;
auto r = std::ref(i);
r = std::ref(j);
r = std::cref(j);
Bir referans sarmalayıcının kopyalanması pratik olarak bir işaretçiyi kopyalamaya eşdeğerdir, bu da olabildiğince ucuzdur. Kullanmanın doğasında olan tüm işlev çağrıları (örneğin, yapılacak olanlar operator()
) tek satırlık olduklarından sadece satır içi olmalıdır.
reference_wrapper
e-postalar std::ref
vestd::cref
aracılığıyla oluşturulur :
int i;
auto r = std::ref(i);
auto r2 = std::cref(i);
Şablon argümanı, başvurulan nesnenin türünü ve cv niteliğini belirtir; r2
a anlamına gelir const int
ve yalnızca bir referans verir const int
. const
İçlerinde functor olan sarmalayıcılara başvurmak için yapılan çağrılar yalnızca const
üye işlev operator()
lerini çağırır .
Rvalue başlatıcılarına izin verilmesi yarardan çok zarar vereceğinden izin verilmez. R değerleri yine de taşınacağı için (ve kısmen kaçınılsa bile garantili kopya eleme ile ), anlambilimini geliştirmiyoruz; bir referans sarmalayıcı pointee'in ömrünü uzatmadığından, sarkan işaretçiler ekleyebiliriz.
Kütüphane etkileşimi
Daha önce bahsedildiği gibi , karşılık gelen argümanı a'dan geçirerek make_tuple
sonuçta bir referansın saklanması talimatı verilebilir :tuple
reference_wrapper
int i;
auto t1 = std::make_tuple(i);
auto t2 = std::make_tuple(std::ref(i));
Bunun forward_as_tuple
şunlardan biraz farklı olduğuna dikkat edin : Burada, bağımsız değişken olarak r değerlerine izin verilmez.
std::bind
aynı davranışı gösterir: Bağımsız değişkeni kopyalamaz, ancak bir reference_wrapper
. Bu bağımsız değişkenin (veya bind
functorun !) Kopyalanması gerekmiyorsa ancak -functor kullanılırken kapsam dahilinde kalırsa kullanışlıdır.
Sıradan işaretçilerden farkı
Ek bir sözdizimsel yönlendirme seviyesi yoktur. İşaretçilerin başvurdukları nesnenin bir değerini elde etmek için referanslarının kaldırılması gerekir; reference_wrapper
s örtük bir dönüştürme operatörüne sahiptir ve sardıkları nesne gibi çağrılabilir.
int i;
int& ref = std::ref(i);
reference_wrapper
s, işaretçilerden farklı olarak, boş bir duruma sahip değildir. Bir referansla veya başka biriylereference_wrapper
başlatılmaları gerekir .
std::reference_wrapper<int> r;
Bir benzerlik, yüzeysel kopya semantiğidir: İşaretçiler ve reference_wrapper
ler yeniden atanabilir.
.
yerine kullandığınız bir işaretçi->