26 Mayıs 2021 Çarşamba

std::views::filter metodu

Giriş
Açıklaması şöyle
In order to provide the amortized constant time complexity required by range, filter_view::begin caches the result in *this. This modifies the internal state of *this and thus cannot be done in a const member function.
Örnek
Elimizde şöyle bir kod olsun. const v olan kod derlenmez.
auto fn_is_l = [](auto const c) { return c == 'l'; };

{
  auto v = "hello"sv | std::views::filter(fn_is_l);
  std::cout << *v.begin() << std::endl; // ok
}

{
  auto const v = "hello"sv | std::views::filter(fn_is_l);
  std::cout << *v.begin() << std::endl; // error
}
Örnek
Şöyle yaparız.
#include <vector>
#include <ranges>
#include <iostream>

int main()
{
  std::vector<int> ints{0,1,2,3,4,5};
  auto even = [](int i){ return 0 == i % 2; };
  auto square = [](int i) { return i * i; };

  for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
    std::cout << i << ' ';
  }
}

$ g++-10 -Wall -Wextra -std=c++20 ranges.cpp 
$ ./a.out 
0 4 16

25 Mayıs 2021 Salı

destroying operator delete - C++20 İle Geliyor

Giriş
Açıklaması şöyle
Prior to C++20, objects' destructors were always called prior to calling their operator delete. With destroying operator delete in C++20, operator delete can instead call the destructor itself.
Örnek
Elimizde şöyle bir kod olsun
#include <iostream>
#include <new>

struct Foo {
    ~Foo() {
        std::cout << "In Foo::~Foo()\n";
    }

    void operator delete(void *p) {
        std::cout << "In Foo::operator delete(void *)\n";
        ::operator delete(p);
    }
};

struct Bar {
    ~Bar() {
        std::cout << "In Bar::~Bar()\n";
    }

    void operator delete(Bar *p, std::destroying_delete_t) {
        std::cout << "In Bar::operator delete(Bar *, std::destroying_delete_t)\n";
        p->~Bar();
        ::operator delete(p);
    }
};

int main() {
    delete new Foo;
    delete new Bar;
}
Çıktı olarak şunu alırız
In Foo::~Foo()
In Foo::operator delete(void *)
In Bar::operator delete(Bar *, std::destroying_delete_t)
In Bar::~Bar()

30 Nisan 2021 Cuma

std::in_place

Örnek
Şöyle yaparız
struct Things
{
    Things(const char* msg1, const char* msg2) : one(msg1), two(msg2) {}
    Unmovable one;
    Unmovable two;
};

int main()
{
    std::optional<Things>{std::in_place, "jadda", "neida"};
}

28 Nisan 2021 Çarşamba

std::endian

Örnek
Şöyle yaparız
void convertBigToLittleEndianIfNecessary(uint32_t& code) {
  if constexpr (std::endian::native == std::endian::little) {
  code = ((code & 0xFF000000) >> 24) |
         ((code & 0x00FF0000) >> 8)  |
         ((code & 0x0000FF00) >> 8)  |
         ((code & 0x000000FF) >> 24);
    }
}

21 Nisan 2021 Çarşamba

std::bit_width

Giriş
Açıklaması şöyle
std::bit_width finds minimum bits required to represent an integral number x as 1+floor(log(x))

22 Mart 2021 Pazartesi

POSIX stat metodu

Giriş
stat(), lstat(), fstat(), atexit() gibi metodlar libc_nonshared.a kütühanesinde tanımlı. Bu static kütüphane de gidip bir .so dinamil kütüphanesini çağırıyor.

11 Mart 2021 Perşembe

std::map [] operator

Giriş
Bu operator eğer aranan key yoksa default constructor kullanarak bir value ile doldurur. Açıklaması şöyle
T& operator[](const key_type& x);
1 Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map.
Eğer value tipinin default constructor metodu yoksa hata alırız. Aşağıdaki kod derlenmez!
std::map< int, std::reference_wrapper< foo > > my_map;
foo a;
my_map[ 0 ] = std::ref( a );
Örnek - primitive tip
Şöyle yaparız
std::map<std::string,std::size_t> counters;
//...
counters[key]++;
Açıklaması şöyle
++counters[key]; is completely valid. std::map::operator[] inserts a value-initialized element if the key does not exist in the map. This is the idiomatic way of doing what you explained.