13 Temmuz 2020 Pazartesi

std::get metodu - Çeşitli Veri Tiplerinden Okuma İçindir

Giriş
std::get şu tipler ile kullanılabilir.
1. std::pair
2. std::tuple
3. std::array
4. std::variant
std::get için include yapmaya gerek yok. Şu tiplerin include dosyası ile geliyor.
#include <array>
#include <tuple>
#include <utility> // std::pair
Parametre Olarak Verilen Sayı Derleme Esnasında Kullanılır
Açıklaması şöyle.
std::get only accepts a template argument which is an expression whose value that can be evaluated at compiling time.
Şu kod derlenmez.
int k = 10;
while(k--){
  std::sort(begin(v), end(v), [](auto const &t1, auto const &t2) {
    return get<k>(t1) < get<k>(t2); // error
  });
}
1. std::get ve pair
Parametre tipleri birebir uymalı yoksa derleme hatası alırız. Şu kod derlenmez.
std::pair<const int, bool> p(42, true);
std::get<int>(p); // expected failure

2. std::get ve tuple
tuple içindeki alanlara std::get ile erişiriz.
Örnek - indeks ile
Şöyle yaparız.
tuple <int, string, int> x=make_tuple(1, "anukul", 100);
cout << get<0>(x);  //1 verir
tuple derleyici tarafından bir anonim struct'a  (anonymous struct) çevrilir. Her get metodu için de kod üretirilir. Dolayısıyla get<0>, get<1> gibi metodlar için
int get_tuple_int_string_int_0()
ve
string get_tuple_int_string_int_1()
gibi metodlar üretilir.
Örnek - indeks kullanmadan
Şöyle yaparız
std::tuple<int,double> mytup( 1, 2.0 );
std::cout << std::get<int>( mytup ) << "\n"; // prints 1
std::cout << std::get<double>( mytup ) << "\n"; // prints 2
std::cout << std::get<std::string>( mytup ) << "\n"; // compiler error
Örnek
std::tuple yok olursa std::get yanlış çalışabilir. Şu kod undefined behavior verir.
#include <tuple>

int main ()
{
  auto f = [] () -> decltype (auto)
  {
    return std::get<0> (std::make_tuple (0));
  };

  return f ();
}
3. std::get ve std::array
Şöyle yaparız.
array<int, 4> arr{3,4,5,67};
cout << std::get<1>(arr) <<endl;
4. std::get ve variant
Örnek - map of variant
Elimizde şöyle bir kod olsun
std::map<std::string,std::variant<float,int,bool,std::string> kwargs; 
kwargs["type"] = "linear"; 
kwargs["flag"] = true; 
kwargs["height"] = 5; 
kwargs["length"] = 4.5F; 
Şöyle yaparız
float f = std::get<float>(kwargs["length"]);
Örnek
variant'ın sakladığı değere erişmek için şöyle yaparız.
using DateOrString = std::variant<DateType, std::string>;

DateOrString api_call(std::string, std::string) {
  // you can return both DateType and std::string
}

// ...
auto result = api_call("...", "...");
auto& str = std::get<std::string>(result);
Örnek
variant'ın sakladığı değere tip ile değil de indeks ile erişmek için şöyle yaparız.
std::get<0>(v);
Diğer
std::get vector için kullanılamaz.
Açıklaması şöyle.
std::get's index being a template parameter allows it to check at compile time whether the index is valid. This is only possible when the container's size is known at compile time too. std::vector has a variable size: you can add or remove elements at run time. This means std::get for vectors would offer zero benefits over operator[] or at.
Şu kod derlenmez.
vector<int> v1{4,5,6,7,9};
cout << std::get<1>(v1) <<endl;

Hiç yorum yok:

Yorum Gönder