&& Otomatik bize ne anlatıyor?
Kod gibi okursanız
auto&& var = foo();
nerede foo herhangi bir işlev değer türü T. tarafından yazılım değişimine göre avantajları nelerdir. Sonra var tip rvalue başvuru bir lvalue 10**. Ama bu var için ne anlamına geliyor? var kaynaklarını çalmak için izin olduğumuzu gösteriyor, değil mi? unique_ptr<> bir özel mülkiyet olduğunu söylemek döndüğünüzde auto&& senin gibi kod bir okuyucu söylemek için kullanmanız gereken herhangi bir makul bir durum var mıdır? Ve örneğin T sınıf türü T&& ne hakkında?
Ben sadece eğer şablon programlama daha auto&& vakaları Scott Meyers tarafından bu makaledeki örnekler Universal References anlatıldığı gibi başka herhangi bir kullanım olup olmadığını anlamak istiyorum.
CEVAP
auto&& var = <initializer> kullanarak diyorsun:Herhangi bir başlatıcı lvalue veya rvalue bir ifade olsun kabul edeceğim ve constness saklayacağım. Bu genellikle için kullanılıriletme(genellikle T&&). Bu çalışır çünkü neden bir "genel başvuru", auto&& T&& will bağlamak içinhiçbir şey.
İyi de neden sadece o olacak çünkü const auto& bir kullanmıyoruz diyebilirsinizayrıcabir şey bağlamak? const bir referans kullanarak sorunu const! Daha sonra olmayan sabit herhangi bir yöne bağlamak veya const işaretlenmemiş tüm üye işlevleri çağırmak mümkün olmayacaktır.
Örnek olarak, ** 26 bir yineleyici ilk unsuru ve değeri bir şekilde yineleyici tarafından işaret değiştirmek istediğiniz düşünün:
auto&& vec = some_expression_that_may_be_rvalue_or_lvalue;
auto i = std::begin(vec);
(*i) ;
Bu kod gayet iyi başlatıcı ifade ne olursa olsun derlenir. auto&& alternatifler aşağıdaki şekilde başarısız:
auto => will copy the vector, but we wanted a reference
auto& => will only bind to modifiable lvalues
const auto& => will bind to anything but make it const, giving us const_iterator
const auto&& => will bind only to rvalues
Yani bunun için auto&& mükemmel çalışıyor! Bu gibi auto&& kullanarak bir örnek aralığı tabanlı for bir döngü içinde. Daha fazla ayrıntı için my other question bkz.
Eğer öyleyse auto&& başlangıçta da bir lvalue veya bir rvalue gerçeği korumak için referans std::forward kullanırsanız, kodunuz diyor ki:Ya bir lvalue veya rvalue ifadeden nesne var, ilk olarak bunu geçersiz kılabilir en verimli şekilde kullanabilmesi vardı hangisi korumak istiyorum.Gibi:
auto&& var = some_expression_that_may_be_rvalue_or_lvalue;
// var was initialized with either an lvalue or rvalue, but var itself
// is an lvalue because named rvalues are lvalues
use_it_elsewhere(std::forward<decltype(var)>(var));
Bu use_it_elsewhere orijinal başlatıcı değiştirilebilir bir rvalue iken onun cesareti performans iyiliği (kopya kaçınmak) için rip sağlar.
Bu var kaynak çalacağımız zaman yapamayacağımız olarak demek ya? Bir şey auto&& bind madem biz vars bağırsaklarını söküp deneyin kendimizi belki olamaz - çok iyi lvalue veya hatta bir sabit olabilir. Ancak 40* *tamamen onun iç yıkım olabilecek diğer fonksiyonlar için bunu yapabiliriz. Biz bunu en kısa sürede, var geçersiz bir durumda olmasını göz önünde bulundurmalıyız.
Şimdi değeri döndürür foo T bir yerde soru, verilen auto&& var = foo();, bu durum için bu geçerlidir. Bu durumda var tipi T&& çıkarılabilir olacağını kesin olarak biliyoruz. Bir rvalue olduğunu kesin olarak bildiğimiz tarihten bu yana 46 **'In kaynaklarını çalmak için izin. gerek yok Bu özel durumdafoo bilerek değer verirsadece okumalı okuyucu olarak:Bu geçici rvalue başvurusu rahatça hareket edebilmem foo, geri alıyorum.
Ek olarak, some_expression_that_may_be_rvalue_or_lvalue gibi bir ifade çıkabilir. ne zaman kayda değer, "iyi kod" durumu. değişebilir bir başka bence Burada yapmacık bir örnek:
std::vector<int> global_vec{1, 2, 3, 4};
template <typename T>
T get_vector()
{
return global_vec;
}
template <typename T>
void foo()
{
auto&& vec = get_vector<T>();
auto i = std::begin(vec);
(*i) ;
std::cout << vec[0] << std::endl;
}
Burada, get_vector<T>() bir lvalue veya rvalue genel türüne bağlı olarak T ya da olabilecek çok güzel ifadesidir. Biz aslında dönüş foo şablon parametresi get_vector türü değiştirin.
foo<std::vector<int>>, get_vector dediğimiz zaman rvalue bir ifade veren değer global_vec dönecektir. Dediğimiz zaman alternatif olarak, foo<std::vector<int>&>, get_vector başvuru global_vec, lvalue ifadenin geri dönecek.
EÄŸer yaparsak:
foo<std::vector<int>>();
std::cout << global_vec[0] << std::endl;
foo<std::vector<int>&>();
std::cout << global_vec[0] << std::endl;
Beklendiği gibi aşağıdaki çıktıyı alıyoruz:
2
1
2
2
Eğer değiştirmek için auto&& kod herhangi biri auto, auto&, const auto&, ya const auto&& o değil sonuç istiyoruz.
auto&& referans bir lvalue veya rvalue ifade ile durumuna bağlı olarak program mantığı değiştirmek için alternatif bir yol tip özellikleri kullanmak için:
if (std::is_lvalue_reference<decltype(var)>::value) {
// var was initialised with an lvalue expression
} else if (std::is_rvalue_reference<decltype(var)>::value) {
// var was initialised with an rvalue expression
}

Otomatik girinti Not Defteri'nde ...
Nasıl arka plan boyutunu otomatik ayar...
Otomatik olarak (veya daha kolay) aÄŸ k...
Nasıl otomatik olarak bir gözlemlenebi...
CKEditor otomatik olarak div sınıfları...