2011-11-29 18 views
5

_Remove_reference T.Neden std :: move() _Remove_reference olmadan çalışmaz? bildiğiniz gibi

için T veya T & & için T & dönüştürme, için var

Ben oyuncu bir ruh hali içinde aşağıdaki kod, hiç beklediğim gibi çalışır, ancak yok yapılan hiçbir fikri neden.

template<class _Ty> 
struct _Remove_reference 
{ // remove reference 
    typedef _Ty _Type; 
    static void func(){ cout << "1" << endl; } 
}; 

// template<class _Ty> 
// struct _Remove_reference<_Ty&> 
// { // remove reference 
// typedef _Ty _Type; 
// static void func(){ cout << "2" << endl; } 
// }; 
// 
// template<class _Ty> 
// struct _Remove_reference<_Ty&&> 
// { // remove rvalue reference 
// typedef _Ty _Type; 
// static void func(){ cout << "3" << endl; } 
// }; 

template<class _Ty> inline 
    typename _Remove_reference<_Ty>::_Type&& 
    move(_Ty&& _Arg) 
{ // forward _Arg as movable 
    typename _Remove_reference<_Ty>::func(); 
    return ((typename _Remove_reference<_Ty>::_Type&&)_Arg); 
} 

int main(){ 
    int a1= 3; 
    int&& a2 = move(a1); // can't convert the a1 to int&& 
    return 0; 
} 

Her şey referans çöken kuralları ve şablon argümanı indirimi ile ilgili sanırım ama kafam karıştı. Bu konudaki merakımın sıkı uyumaları için paramparça olması gerekiyor.

Şimdiden teşekkürler.

cevap

8

template<class _Ty> inline 
typename _Remove_reference<_Ty>::_Type&& 
move(_Ty&& _Arg) 

Eğer move(a1) yapmak

, _Ty int& olarak çıkarılır göz önüne alındığında. _Ty&& böylece hala nedeniyle kurallarını çöken referansa int& olacağını, bu nedenle bunun bir rvalue referans yapmadan önce int almak için başvuru kaldırmak gerekir.

Bu şablon argümanı kesinti kurallarının özel bir durumudur. T&& olan ve T öğesinin bir şablon parametresi olduğu bir işlev bağımsız değişkeniniz varsa, bu durumda işlev için bir lvalue (yani adlandırılmış bir nesne veya bir değer referansı) iletirseniz, ,olarak belirtilir. X, lvalue nesnesinin türüdür. . Işlevine bir rvalue (geçici veya bir referans) iletirseniz, T sadece X olarak çıkarılır.

örn. move(42)int olmak _Ty deduces ise move(a1) tahmin eder _Ty, int& olması.

BTW: Bu kodu derleyicinin standart kitaplığından aldığınızı sanıyorum --- önde gelen alt çizgi ile yazılmış adlar ve büyük harf _Like _Bu derleyici ve standart kitaplık uygulaması için ayrılmıştır.

+0

Teşekkürler. Bunu takdir ediyorum. Ama neden kodun açıklamasını kaldırmam gerektiğini merak ediyorum? _remove_reference'ın amacı bunları T'ye dönüştürüyorsa, neden şablon uzmanlığı versonuna ihtiyacım var? –

+1

Uzmanlık alanları, _Remove_reference’ın nasıl çalıştığıdır. Birincil şablon her şeyle eşleşir ve aynı türden döner, bu nedenle '_Remove_reference :: type' sadece' int' dir. Referanslar için kısmi uzmanlık referansları yapar. '_Remove_reference ', ilk kısmi uzmanlık ile eşleşir, bu nedenle birincil şablon yerine kullanılır. ('_Ty ve 'int ve' böylece), böylece de _Remove_reference :: type'' int' bir typedef ** Bu uzmanlık ** içinde, '_Ty' sadece 'int' olup. –

+1

Referans çökmesi için bkz. Http://thbecker.net/articles/rvalue_references/section_08.html. Bütün makale, aslında, sayfa 1'den, iyi bir okumadır. Şeyler bağlamını almak için baştan oku. – wilhelmtell

İlgili konular