5 Mart 2019 Salı

rvalue Nedir

rvalue Değişkenin Adresi
Normalde rvalue değişkenin adresiyle ilgilenmemek gerekir.

Örnek
Aynı adres tekrar tekrar rvalue değişken için kullanılabilir.
Örnek
Elimizde şöyle bir kod olsun
const int *funct(const int &x) { return &x; }
Şöyle yaparız
// same address
std::cout << funct(3) << std::endl; //#1
std::cout << funct(4) << std::endl; //#2
Ancak aynı ifade içinde derleyici mevcuren farklı adresler kullanacaktır. Şöyle yaparız
// different addresses
std::cout << funct(3) << std::endl << funct(4) << std::endl; //#3
Açıklaması şöyle
Two alive objects in C++ (almost) always have different addresses.

Since temporaries in #1 #2 have non-overlapping lifetimes, the compiler is free to reuse the storage of #1 for #2 .

But in #3 all temporaries are alive until the end of the expression (for obvious reasons) and in this case they have to have different addresses.
rvalue ve & operator
Açıklaması şöyle. Adresle ilgilenmememiz için bize zorluk bile çıkarılmış :)
Now, there's an expression category rule that you can't apply & to an expression of the rvalue category. The purpose of this rule and these categories is to avoid errors where a temporary object is used after it is destroyed. 
Örnek
Şu kod derlenmez.
int *p = &5;    // not allowed due to category rules
*p = 6;         // oops, dangling pointer
Ancak rvalue değişkenin adresini almak mümkün. Şöyle yaparız.
template<typename T> auto f(T&&t) -> T& { return t; }
// ...
int *p = f(5); // Allowed
*p = 6;        // Oops, dangling pointer, no compiler error message.
rvalue Değişken lvalue Haline Gelebilir
Örnek
Şöyle yaparız.
int arr[] = {1, 2};
int* p = &arr[0];
*(p + 1) = 10;   // OK: p + 1 is an rvalue, but *(p + 1) is an lvalue

22 Şubat 2019 Cuma

Pointer To Array

Giriş
Array'e pointer elde etmek için
array
&array
&array[0]
kullanılabilir.

Görsel olarak şöyledir.
+----------+----------+----------+----------+----------+
| array[0] | array[1] | array[2] | array[3] | array[4] |
+----------+----------+----------+----------+----------+
^
|
&array[0]
|
&array
Örnek
Şöyle yaparız. p pointer to array ve daha sonra istesek başka bir yere de point ettirebiliriz.
int a[5] = {1,2,3,4,5}
int * p = a;
Örnek
Şöyle yaparız.
int array[5] = { 10,11,12,13,14};

std::cout << array << std::endl;
std::cout << &array << std::endl;
std::cout << &array[0] << std::endl;
Örnek
Şu ise derlenmez.
int a[5] = {1,2,3,4,5};
int*& ref = a;
Açıklaması şöyle
a is not a pointer, it is an array. It has the type int[5]. What it can do it is decay to a pointer int*, which is what happens in the first case. So, taking a reference to p is ok.

Now for the second case. Remember that a is not a pointer. So, there is an implicit conversion happening from int[5] to int*. The result of that conversion is a prvalue. But you can't bind a non-const lvalue reference (which is what ref is) to an rvalue! So the code fails to compile.
Örnek
Pointer To Array'in adresini almak. Elimizde şöyle bir kod olsun.
int *pArray = new int[5];

std::cout << pArray << std::endl; //İlk elemanın adresi
std::cout << &pArray << std::endl; //Pointer'ın adresi
std::cout << &pArray[0] << std::endl;//İlk elemanın adresi
Görsel olarak şöyledir.
+--------+       +-----------+-----------+-----------+-----------+-----------+-----+
| pArray | ----> | pArray[0] | pArray[1] | pArray[2] | pArray[3] | pArray[4] | ... |
+--------+       +-----------+-----------+-----------+-----------+-----------+-----+
^                ^
|                |
&pArray          &pArray[0]

21 Şubat 2019 Perşembe

std::add_lvalue_reference

Bu metodun ne işe yaradığını anlamadım. İlk gördüğüm yer burası

Reference Collapsing

Giriş
const T& şeklindeki parametre kullanan template kod, eğer <int&> şeklinde çağrılırsa parametrenin const olmaması anlamına gelir.

Kodu her zaman şöyle çağırmak gerekir.
g<int>(n);
// or just
g(n);
Şu şekildeki çağrılar yanlış
 int n{};
g<int&>(n);
Açıklaması şöyle.
...so you have specified that T is a int&. When we apply a reference to an lvalue reference, the two references collapse to a single one, so int& & becomes just int&. Then we get to the rule from [dcl.ref]/1, which states that if you apply const to a reference it is discarded, so int& const just becomes int&...
Örnek
Elimizde şöyle bir kod olsun.
template<typename T>
void f(T a, const T& b)
{
  ++a; // ok
  ++b; // also ok!
}

template<typename T>
void g(T n)
{
  f<T>(n, n);
}

int main()
{
  int n{};
  g<int&>(n);
}