R-Value References (Sağ Taraf Referansları) - 1

Sağ taraf referansları (r-value references) C++11 standartlarıyla C++ diline eklenmiş en önemli araçlardan biridir. Fakat kavram biraz karmaşık bir şekilde standarlaştırılmış ve bu durum insanların anlamasını fazlasıyla zorlaştırmaktadır. Şimdi bu konuyu anlaşılır hale getirmeye çalışalım.
tüm referans ağacı

Basitleştirilmiş bir tanım yapmak gerekirse; Atama işlecinin hem sol tarafında hem sağ tarafında yer alabilen ifadeler sol taraf değeridir. Atama işlecinin yalnızca sağ tarafında yer alabilen ifadeler sağ taraf değeridir. Daha kısa bir tanım yapmak geekirse bellekte bir yer tahsis edilmiş değerlere sol  taraf değeri; bellekte bir yer tahsis edilmemiş değerler ise sağ taraf değeridir

R-Value References (Sağ Taraf Referansları)

T bir tür olmak üzere, sağ taraf referansı olarak T&& şeklinde, sol taraf referansı olarak T& şeklinde ifade edilecektir. Bir sağ taraf referansı birkaç istisna dışında sol taraf referanslar (T&) gibidir. Ayrımın olduğu noktalardan biri ise sol taraf referans ve sağ taraf referans paremetrelerine sahip aynı isimli fonksiyonlar bir arada (overload) bulunduğunda sol taraf değerleri için sol taraf referansa sahip parametreli fonksiyon, sağ taraf değerleri için sağ taraf referansa sahip parametreli fonksiyon çağrılır.

sağ taraf ve sol taraf referanslara ilişkin overload örneği

  1. void func(int &x);       //sol taraf referansı parametreli
  2. void func(int &&x);    //sağ taraf referans parametreli
Yukarıda kod 
  • func(69); şeklinde bir çağrımda 69 bir sağ değer olduğu için 2 numaralı fonksiyon
  • int i = 69;
    func(i); şeklinde bir çağrımda i bir sol değer olduğu için 1 numaralı fonksiyon
Öncelikle normal bir referansa (sol taraf değerine bağlanan referans) verilen ilk değerin aynı türden nesne belirten bir ifade (yani sol taraf değeri)  olması gerektiğini aşağıdaki örnek kodla anımsayalım:
sol taraf referanslara ilişkin atama örneği
Sol taraf referanslı bir değere doğrudan sağ taraf referanslı bir değer atanamayacağına dair hata kodu aşağıdaki gibidir: 


Bir sağ değer referans'a verilen ilk değerin aynı türden nesne belirten bir ifade yani sağ değer olması gerektiğini aşağıdaki örnek kodla anımsayalım:
sağ taraf referanslara ilişkin atama örneği
Sağ değer referans'a ilk değerin doğrudan sol taraf değer atanamayacağına dair hata kodu aşağıdaki gibidir: 

Sağ taraf değeri belirten bazı ifadeler;

  • Sabitler
    Örneğin:
    2, 3,1, vb. //Sağ taraf değeri
  • Çeşitli aritmetik operatörlerle oluşturulan ifadeler 
    Örneğin:
    a+b/c, vb.    //Sağ taraf değeri
  • Geri dönüş değeri referans olmayan fonksiyon çağrıları
    Örneğin:
    int foo();
    int &&bar();
    yukarıdaki prototipleri görünen foo(), bar(); fonksiyonlarını çağıran ifadeler //Sağ taraf değeri
  • Geçici nesneler
    Örneğin:
    class Foo {
     public:
      //...
    };

    ...
    Foo(); //Sağ taraf değeri
Sağ taraf referansları başlıca iki soruna çözüm getirmek için ortaya çıkan bir kavramdır. Bunlar;
  • Taşıma semantiğinin (move semantics) gerçekleştirilmesi
  • Mükemmel gönderim (perfect forwarding)
Bir sonraki bölümde bu iki kavramı detaylı anlatıp Sağ Taraf Referansları (R-Value References) kavramını daha anlaşılır hale getirmeye çalışacağız.

Not 

  • Dekleratördeki && atomlarını ** atomlarına benzeterek referans referansları varsayımında bulunmak tamamen hatalıdır. Bu yapay bir notasyondur.
  • double dval = 3.2;
    const int &ival = dval;
    bir atamada aslında olan:
    double dval = 3.2;
    const int itmp = dval;
    const int &ival = itmp;
  • Sol taraf değerine bağlanan referanslara verilen ilk değerlerin nesne belirten ifadeler olması zorunludur. Fakat sağ taraf değerine bağlanan referanslara verilen ilk değerler için nesne belirtme zorunluluğu yoktur.
    int &&val = foo();
    int &val2 = 5; //Geçersiz