SORU
5 Kasım 2012, PAZARTESİ


&& 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
5 Kasım 2012, PAZARTESİ


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
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • DorkmanScott

    DorkmanScott

    14 NİSAN 2006
  • spederson7

    spederson7

    17 Temmuz 2006
  • Whizzpopping

    Whizzpopping

    10 Kasım 2005