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_wrappers 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_wrapperssadece 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_wrappere-postalar std::refvestd::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; r2a anlamına gelir const intve 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_tuplesonuçta bir referansın saklanması talimatı verilebilir :tuplereference_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::bindaynı davranışı gösterir: Bağımsız değişkeni kopyalamaz, ancak bir reference_wrapper. Bu bağımsız değişkenin (veya bindfunctorun !) 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_wrappers ö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_wrappers, 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_wrapperler yeniden atanabilir.
.yerine kullandığınız bir işaretçi->