28 Ocak 2019 Pazartesi

Zero Initialization

Giriş
Açıklaması şöyle.
One of the founding principals of c++ is to not force developers to pay for what they don't use. If you write something like int x; x = 1; then you shouldn't have to pay for the zero initialization of x, even if that cost happens to be very tiny
Global Variable
Global değişkeni kendisiyle ilklendirmek zero initialization'a sebep olur.

Örnek
Şöyle yaparız
int i = i;

int main() { 
 int a = a;
 return 0;
} 
Compiler Generated Default Constructor
Sınıfa default constructor yazarsak yani şöyle yaparsak
MyTest() = default;
sınıfın alanları zero initialization'a tabi tutulur.

Örnek
Şöyle yaparız.
struct foo {
  foo() = default;
  int a;
};


int main() {
  foo a{};
  std::cout << a.a;
}
Çıktı olarak şunu alırız
0

17 Ocak 2019 Perşembe

std::hash Yapısı

Giriş
std::hash template parametresi için özelleşmiş bir sürü kod C++ ile geliyor.

Constructor
Şöyle yaparız.
std::hash<std::string> h;
operator () metodu
Bir çok kodda std::hash değişkeni oluşturmak yerine şöyle yapılıyor
return hash<string>() (sd.isbn());
Aslında şu kod ile aynıdır.
std::hash<std::string> temp;
return temp (sd.isbn());
Örnek - boost::multiprecision::cpp_int
Şöyle yaparız.
template <typename T> struct hash_str {
  size_t operator()(const T &t) const { return std::hash<std::string>()(t.str()); }
};

using bmp::cpp_int;
boost::unordered_map<cpp_int, cpp_int, hash_str<cpp_int> > mp;
Örnek - long long
Şöyle yaparız.
long long sum {0};
std::size_t value = std::hash<long long>()(sum);
Örnek - GUID
Eğer 64 bit olan ancak tipi farklı bir değişken varsa şöyle yapabiliriz.
namespace std
{
  template<>
  struct hash<GUID>
  {
    std::size_t operator()(const GUID& gUid) const
    {
      return std::hash<uint64_t>()(reinterpret_cast<const uint64_t>(gUid));    }
  };
}
Örnek - std::null_ptr
 Açıklaması şöyle.
Each standard library header that declares the template std::hash provides enabled specializations of std::hash for std::nullptr_t and all cv-unqualified arithmetic types (including any extended integer types), all enumeration types, and all pointer types.
Şöyle yaparız
std::hash<std::nullptr_t> h;
return h(nullptr);
Örnek - std::string
Şöyle yaparız.
std::string name = ...;
std::hash<std::string> h;
std::size_t value = h (name);

std::random_device Sınıfı - Yaratması Maliyetlidir

Giriş
Şu satırı dahil ederiz.
#include<random>
Açıklaması şöyle
std::random_device may be expensive to create. It may open a device feeding it data, and that takes some time. It can also be expensive to call because it requires entropy to deliver a truly random number, not a pseudo random number.
Donanım tabanlıdır. Eski bilgisayarlarda donanım tabanlı dağılım için ne yapıldığını anlatan bir yazı şöyle.

Eğer donanım desteği yoksa algoritma tabanlı bir üretece dönüşür. Uyarı vermeden yapılan bu geçiş istenmeyen sonuçlara sebep olabilir. Açıklaması şöyle.
std::random_device, introduced in C++11, is not recommended because its specification leaves considerably much to be desired. For example, std::random_device can fall back to a pseudorandom number generator of unspecified quality without much warning.

Constructor
Şöyle yaparız.
std::random_device rd;
entropy metodu
entropy şu anlama gelir.
entropy is the measure of surprise
Windows'ta bu metod hep 32 döner.

Linux'ta işletim sisteminin entropisini görmek için şöyle yaparız.
cat /proc/sys/kernel/random/entropy_avail
Eğer donanım tabanlı bir üreteç yoksa yine yazılım tabanlı bir üreteç kullanılır. Açıklaması şöyle.
std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case each std::random_device object may generate the same number sequence.
Bu durumda sınıfın entropy metodu 0 döner. Şöyle yaparız.
std::random_device rd;
std::cout << rd.entropy();
Çıktı olarak şunu alırız.
0
Diğer Üreteçleri İlklendirme - mt19937
Şöyle yaparız.
std::random_device rd;
std::mt19937 eng(rd());
Bu kod eleştirilere maruz kalıyor. Sebepleri şöyle. Tüm bunlar şu anlama geliyor mt19937'yi ilklendirmek için random_device yeterli değil.
1. rd() returns a single unsigned int. This has at least 16 bits and probably 32. That's not enough to seed MT's 19937 bits of state.

2. Using std::mt19937 gen(rd());gen() (seeding with 32 bits and looking at the first output) doesn't give a good output distribution. 7 and 13 can never be the first output. Two seeds produce 0. Twelve seeds produce 1226181350.

3. std::random_device can be, and sometimes is, implemented as a simple PRNG with a fixed seed. It might therefore produce the same sequence on every run. (Link) This is even worse than time(NULL).



requires Anahtar Kelimesi

Giriş
C++20 ile geliyor. requires constaint ve requires expression diye iki farklı kavram var.
Açıklaması şöyle
A requires constraint does not have to use a requires expression. It can use any more-or-less arbitrary boolean constant expression. Therefore, requires (foo) must be a legitimate requires constraint.

A requires expression (that thing that tests whether certain things follow certain constraints) is a distinct construct; it's just introduced by the same keyword. requires (foo f) would be the beginning of a valid requires expression.
Örnek - expression
Açıklaması şöyle.
requires-expression can also be used in a requires-clause ([temp]) as a way of writing ad hoc constraints on template arguments
The first requires introduces the requires-clause, and the second introduces the requires-expression.
Şöyle yaparız.
template<typename T>
  requires requires (T x) { x + x; }
    T add(T a, T b) { return a + b; }

16 Ocak 2019 Çarşamba

strspn metodu

Giriş
Şu satırı dahil ederiz.
#include <string.h>
İkinci parametre seti içinde olmayana ilk karakterde durur.

Örnek
Şöyle yaparız
const char user_input[] = "101th";
const char bdigits[] = "01";

int i = strspn (user_input, bdigits);
printf("Not a binary digit at position %d.\n",i);