2 Mart 2020 Pazartesi

POSIX strcasecmp metodu

Giriş
Açıklaması şöyle.
The strcase*-functions are not Standard C, but a POSIX extension.
Açıklaması şöyle. Büyük küçük harf farkı dikkate alınmaz.
The strcasecmp() function performs a byte-by-byte comparison of the strings s1 and s2, ignoring the case of the characters. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2.
Önce her ley küçük harfe çevrilir. Açıklaması şöyle.
In the POSIX locale, strcasecmp() and strncasecmp() shall behave as if the strings had been converted to lowercase and then a byte comparison performed. The results are unspecified in other locales.
Örnek
Elimizde şöyle bir kod olsun
#include <stdio.h>
#include <string.h>

int main()
{
  // ASCII values
  // 'A' = 65
  // '_' = 95
  // 'a' = 97
  printf("%i\n", strcmp("A", "_"));
  printf("%i\n", strcmp("a", "_"));
  printf("%i\n", strcasecmp("A", "_"));
  printf("%i\n", strcasecmp("a", "_"));
  return 0;
}
Çıktı olarak şunu alırız
-1  # "A" is less than "_"
1   # "a" is more than "_"
2   # "A" is more than "_" with strcasecmp ???
2   # "a" is more than "_" with strcasecmp

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ı