2 Mart 2020 Pazartesi

decltype

Giriş
decltype C++11 ile gelen yeni kelimelerden birisi. Genellikle template programlamada kullanılıyor. Kendisine verilen ifadenin tipini döndürür. Aynı sizeof() gibi derleme esnasında çalışır.

İlgili olarak decltype auto Return Type yazısına da bakabilirsiniz.

1. Type Bulmak İçin Kullanımı
1.1 decltype () ve decltype (()) Farkı
decltype () ve decltype (()) farklı anlamlara gelir. Eğer int a = 0 ise decltype(a) int sonucunu verir. decltype((a)) ise int& sonucunu verir.

Yani decltype((...)) adres anlamına gelir.

Örnek
Şöyle yaparız.
const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17;        // type is const int&&
decltype(i) x2;                 // type is int
decltype(a->x) x3;              // type is double
decltype((a->x)) x4 = x3;       // type is const double&
Örnek
Şöyle yaparız.
#include <iostream>
#include <type_traits>

struct S {
  int v = 0;  
};

int main() {
  S s;
  std::cout << std::is_same<decltype(s.v), int>() << std::endl;
  std::cout << std::is_same<decltype((s.v)), int&>() << std::endl;
}
Örnek
Diğer örnekler ise şöyle.
#include <vector>
int main()
{
  const std::vector<int> v(1);
  auto a = v[0];        // a has type int
  decltype(v[0]) b = 1; // b has type const int&, the return type of
                        // std::vector<int>::operator[](size_type) const
  auto c = 0;           // c has type int
  auto d = c;           // d has type int
  decltype(c) e;        // e has type int, the type of the entity named by c
  decltype((c)) f = c;  // f has type int&, because (c) is an lvalue
  decltype(0) g;        // g has type int, because 0 is an rvalue
}
1.2 Entity (struct,class) için kullanım

Örnek
Değişken tanımlamak için şöyle yaparız.
struct Bar
{
    Bar(int) {} // implicitly constructable
}

struct Bar2
{
    Bar2(int) {} // implicitly constructable
}

struct Foo
{
    static Bar var;
}

struct Foo2
{
    static Bar2 var;
}

template <typename T>
void dummy()
{
    decltype(T::var) myVar = 42;
}

dummy<Foo>(); // myVar is of type Bar1
dummy<Foo2>(); // myVar is of type Bar2
auto myAutoVar = 42; // type is int
Pointer veya Reference ile Kullanımı
decltype Pointer veya Reference ile Kullanımı yazısına taşıdım.

1.2 Expression İçin Kullanım
Yeni bir değişken tanımlarken tipini belirtmek için decltype kullanılabilir. Açıklaması şöyle.
a) if the value category of expression is xvalue, then decltype yields T&&;
b) if the value category of expression is lvalue, then decltype yields T&;
c) if the value category of expression is prvalue, then decltype yields T.
xvalue kelimesini açıklaması şöyle
An xvalue ("expiring value") expression is an expression that has identity and can be moved from.
prvalue kelimesinin açıklaması şöyle
A prvalue ("pure rvalue") expression is an expression that does not have identity and can be moved from.
a + b, a % b, a & b, a << b, and all other built-in arithmetic expressions;
prvalue xvalue tipine std::move ile değiştirilebilir.
static_assert(std::is_same<decltype(std::move(i + j)));
1.3 Template İçinde Placeholder Olarak Kullanımı

2. STL ile kullanım örnekleri
map tanımlama
Elimizde bir sınıf olsun
class search_object
{
public:
  unsigned int index;
  unsigned int search_field;
};
Sınıfın bir alanının tipini STL veriyapısı ile kullanmak isterse şöyle yaparız
std::map<decltype(search_object::index), search_object> container;
map iterator
Elimizde bir map olsun
map<int,double> m;
iterator tanımlamak istersek şöyle yaparız.
// Here! The compiler will replace the `decltype(m)` placeholder by `map<int,obj>`
decltype(m)::iterator it = m.begin();
3. Method Signature İçin Kullanımı
decltype Method Signature İçin Kullanımı yazısına taşıdım

4. Member Field İçin Kullanımı
























Hiç yorum yok:

Yorum Gönder