26 Mart 2020 Perşembe

decltype Pointer ile Kullanımı

Giriş
Bazı problemler şöyle
- Pointer'ın point ettiği nesnenin tipini bulmak
- Pointer'ın adresini bulmak

Örnek - Pointer'ın Point Ettiği Nesnenin Tipini Bulmak
1. Eğer değişken pointer ise, dereference veya std::decay ile kullanılabilir. Dereference ile kullanım şöyle olur. Şöyle yaparız. Burada amaç foo* tipini foo haline getirmek. Yani pointer'ın point ettiği nesnenin tipini bulmak. Burada decltype(*a) şeklide kullanılıyor.
#include <memory>

int main()
{
  int* a = new int(2);

  std::unique_ptr<std::decay<decltype(*a)>::type> p(a);
}
C++14 ile decay biraz daha kısaltılarak decay_t haline gelmiş. Böylece std::decay<>::type şeklinde yazmak zorunda kalmıyoruz.
#include <memory>

int main()
{
  int* a = new int(2);

  std::unique_ptr<std::decay_t<decltype(*a)>> p(a);
}
2. Ya da remove_reference_t kullanabiliriz. Şöyle bir kod olsun.
int a = 42;
int *p = &a;
Bu kodu remove_reference_t ile kullanabiliriz.
std::numeric_limits<
    std::remove_reference_t<decltype(*p)>
>::max();
Örnek - const Pointer
Entity Pointer'ın const olması decltype sonucunu const yapmaz.
struct A { double x; };
const A* a = new A();
decltype(a->x) x3; // type is double
Örnek - Pointer'ın Adresini Almak
Elimizde şöyle bir kod olsun. Bu kodlar pointer'ın adresini almaz. 
template <typename T>
struct Foo
{
    Foo(T arg) : ptr(arg) {}
    T ptr;
};

int main() 
{
    int* a = new int(6);
    Foo<decltype(a)> foo1(a); // ptr is a copy of a pointer
    Foo<decltype(&a)> foo1(&a); // ptr seems to be a pointer to a pointer
}
Şöyle yaparız
Foo<decltype(a) &> foo1(a).
veya şöyle yaparız
#include <functional>

template <typename T>
struct Foo
{
  Foo(T arg) : ptr(arg)
  {
  }
  T ptr;
};

int main()
{
  int* a = new int(6);

  Foo<std::reference_wrapper<int*>> foo1(std::ref(a));
  foo1.ptr[0] = 1;  // ok

  // This also works
  int* b = new int(6);
  Foo<std::reference_wrapper<decltype(b)>> foo2(std::ref(b));
  // and this too
  foo1 = foo2;

  // Or, if you use c++17, even this
  Foo foo3(std::ref(b));
}
Örnek - Pointer'ın Kaç Seviye Olduğunu Bulmak
Şöyle yaparız. Burada decltype<(T&)>() şeklide kullanılıyor. Pointer'ın adresi
template <class T, class = void>
struct deref_level {
    enum : std::size_t { value = 0 };
};

template <class T>
struct deref_level<T, decltype(void(*std::declval<T const &>()))> {
    enum : std::size_t { 
      value= deref_level<decltype(*std::declval<T const &>())>::value + 1
    };
};

Hiç yorum yok:

Yorum Gönder