2016-11-26 19 views
17

fark Scott Meyers tarafından bu örnekte yeterince açık yapıldı: Biz, bu nedenle örnek bir anlaşılabilir bağlam olduğundaBu bir yönlendirme referansı mı? rvalue referanslar ve yönlendirme referanslar arasında

Widget&& var1 = someWidget;  // here, “&&” means rvalue reference (1) 

auto&& var2 = var1;    // here, “&&” does not mean rvalue reference (2) 

template<typename T> 
void f(std::vector<T>&& param); // here, “&&” means rvalue reference (3) 

template<typename T> 
void f(T&& param);    // here, “&&”does not mean rvalue reference (4) 

Esas ayrım olur (3) açık bir şekilde belirtir biz bu vector<...>&&, T (4) durumunda ise ("değer kategorisi" olarak kategorize edilmiş) (ve referans çöken kurallarını uyguladıktan sonra).

Fakat biraz daha karmaşık desen eşleştirmesiyle ne olur? örneğin aşağıdaki durumunu ele alalım:

template <template <class...> class Tuple, class... Ts> 
void f(Tuple<Ts...>&& arg) 
{ 

} 

&& burada ne anlama geliyor?

+1

Dönüştürülebilir içerik önemli değil. (3) ve (4) her ikisinin de çıkarılabilirdir. – Oktalist

cevap

14

Son örneğinizde, arg bir rvalue başvurudur.

bir yönlendirme referans

ve Tuple<Ts...> bir şablon parametresi olmayan bir ev-vasıfsız şablon parametresine bir rvalue referanstır.

([temp.deduct.call] 'den Atıf.)

9

bir rvalue referansı, bir yönlendirme referanstır.

template<typename... Ts> 
struct foo {}; 

//f function definition 

int main() { 
    foo<int, double> bar; 
    f(bar); // fails! Cannot bind lvalue to rvalue reference 
    f(foo<int, double>{}); // ok, rvalue is passed 
} 
1

kavram yönlendirme referansı değildir:

emin olmak için en kolay yolu başarısız olursa değilse, o zaman bir yönlendirme referansı, o zaman bir rvalue referanstır, bir lvalue geçmek denemektir Standart bir konsept olarak, onu gördüğünüzde onu tanımak yararlıdır, ancak eğer anlamak ve doğru bir şekilde ele almak istiyorsanız referans aritmetiğini anlamalısınız.

bir yönlendirme referansı kavramının arkasında ne

referans aritmetik (Ben Meyer'in kitabı da bu konuda bir bölüm olduğuna inanıyorum):

  • & & & & = & &
  • & & & = &
  • & & & = &
  • & & = &

en böyle bir durumda bir yönlendirme referansı

template<class T> 
void foo(T&&); 
//... 
const int i=42; 
foo(i); // the compiler will defines T = const int & 
     //   T&& = const int & && = const int & 
     // => the compiler instantiates void foo<const int &>(const int &); 
foo(6*7);// the compiler will defines T = int 
     //   T&& = int && 
     // the compiler instantiates void foo<int>(int &&); 

ile derleyici şablon türü kesinti simüle edelim, şablon foo örneğinin can bir işlev üretir argüman referansı veya argüman referans değerlerini alan fonksiyonlarla argüman alır: bir yönlendirme referansı Şablon tipi kesintiye bağlı olarak bir rvalue referansı veya bir referans referansı. Böyle bir durumda, parametre bir lvalue veya bir xValue olarak ya geçirilecek çünkü böyle adlandırılmış ve bir fonksiyon vardır bildirirseniz bu T&& std::forward<T>(T&& a)

işi olduğunu edilir:

template<class T> 
void foo(ATemplateClass<T> && a); 

derleyici tarafından T için türetilen türden ne olursa olsun, bir referans referans parametresi alırsınız.

+0

Numunenizden emin misiniz? Foo (42) ve foo (6 * 7) 'nin aynı teknede olduğuna inanıyorum: https://godbolt.org/g/jOEK9b – RTempete

+0

@RTempete Gönderinin bir kısmı yanlış görünüyor: Gördüğünüz gibi int && '- aynı şeyi değil, 'const' değerini çıkar. Eğer Oliv, niçin 'const' diye düşünmeleri gerektiğini açıklarsa ve/veya a'nın (-O0'da bile en iyi duruma getirilmiş olan) önemsiz olup olmadığına göre bir fark olması gerekirse, bu çok daha fazla olurdu. işe yarar. –

+0

Maalesef, örnek kodda iki hata oluştu. f (42) -> rvalue referansı ve f (6 * 7) da. – Oliv