10 Ağustos 2021 Salı

Deleted Function

Giriş
Deleted Constructor
Deleted Destructor
olabilir.
Ayrıca deleted generic function da olabilir.

Örnek
Şöyle yaparız
// API function
void api(void* p) {
  // ... 
}

// Special case for nullptr
inline void api(std::nullptr_t) {
  api((void*)nullptr);
}

// Everything else is disabled
template <class ...T>
void api(T&&... t) = delete;

int main() {
  int i = 0;
  void* p = &i;
  api(p); // Compiles
  // api(&i); // Doesn't compile
}

std::views::common metodu

Giriş
std::ranges::range tipinden olan değişkeni, STL Container gibi kullabilmeyi sağlar.
Örnek
Şöyle yaparız
template <std::ranges::range R>
auto to_vector(R&& r) {
    auto r_common = r | std::views::common;
    return std::vector(r_common.begin(), r_common.end());
}
Örnek
Şöyle yaparız
#include <cmath>
#include <numeric>
#include <ranges>
#include <utility>

template<typename Container>
auto mean_and_stddev(const Container& values)
{
  auto len = static_cast<double>(values.size());
  auto mean = std::accumulate(values.begin(), values.end(), 0.0) / len;
  auto sdv =                   // squared differences view
      values
      | std::views::transform([mean](auto d){ auto x = d - mean; return x*x; })
      | std::views::common;
  auto stddev = std::sqrt(std::accumulate(sdv.begin(), sdv.end(), 0.0) / len);
  return std::pair{ mean, stddev };
}

1 Temmuz 2021 Perşembe

C++ Filename Extensions

Giriş
C++ ve bir çok daha başka dil (Pascal, BASIC, C gibi) dosya uzantısının ne olması gerektiğini belirtmez. Bjarne Stroustrup'un "The C++ Programming Language (2nd edition, 1991)" kitabındaki Ch.4, p114'teki açıklaması şöyle açıklaması şöyle
Header files are conventionally suffixed by .h and files containing function or data definitions by .c. ... Other conventions, such as .C, .cxx, .cpp, and .cc, are also found. The manual for your compiler will be quite specific about this issue.

21 Haziran 2021 Pazartesi

Name Mangling - Sadece C++'ta Vardır

Giriş
Açıklaması şöyle. Yani Linker için gereklidir.
Name mangling is the encoding of function and variable names into unique names so that linkers can separate common names in the language. 
Eğer C kütüphanesini C++ ile kullanmak istersek name mangling olmasını istemeyiz. Bu durumda extern "C" kullanmak gerekir.

Örnek
Açıklaması şöyle
If you have ever looked at an objdump of a C++ program, you have likely seen something like this:

_ZN3foo3bar3bazI6sampleEE3quxvi3fo

This is a C++ mangled symbol, which encodes the namespaces, classes, and function/template arguments, using the Itanium ABI.

Specifically, it is for the following function:

void foo::bar::baz<sample>::qux(int, foo);
Rakamların açıklaması şöyle
- All mangled symbols start with _Z.
- Everything is case sensitive.
- All identifiers are encoded as <length><name>, where <length> is the positive length of <name> in base 10, so foo is encoded as 3foo, sample is encoded as 6sample, etc.

7 Haziran 2021 Pazartesi

std::chrono::year_month_day

Örnek
Şöyle yaparız. Bu kod UTC saate göre çalışır
#include <chrono>

bool IsTodayChristmas() {
    using namespace std::chrono;

    constexpr month_day Christmas = {December / 25};
    auto Now = year_month_day{floor<days>(system_clock::now())};

    // either
    return Now == Christmas / Now.year();
    // or
    return Now.month() / Now.day() == Christmas;
}
Yerel zamana göre çalışmak istersek şöyle yaparız
bool IsTodayChristmas() {
    using namespace std::chrono;

    constexpr month_day Christmas = {December / 25};
    auto Now_local = current_zone()->to_local(system_clock::now());
    auto Today = year_month_day{floor<days>(Now_local)};

    return Today == Christmas / Today.year();
}

26 Mayıs 2021 Çarşamba

std::map.erease metodu

erase metodu - C++98
İmzası şöyle
void erase (iterator pos);           // (until C++11)
Açıklaması şöyle
The erase operations of the node-based containers (maps, sets, lists) invalidate only iterators and references to the element that was erased, but not any other iterators.
Yani sadece erase edilen eleman'a olan iterator bozulur. Bir başka thread içinde diğer elemanlara iterator varsa bunlar etkilenmez.

STL içindeki bazı veri yapıları kendisine ait erase() metoduna geçilen iterator nesnesini otomatik olarak ilerletiyor. Ancak map bu veri yapılarından değil. erase() metodu void dönüyor. Dolayısıyla döngü içinde bir şey silmek istiyorsak aşağıdakine benzer bir kod parçası kullanmamız gerekli.
for (it = tableMap.begin(); it != tableMap.end(); )
{
    if (tableId == it->first.first) { tableMap.erase(it++); }
    else                            { ++it; }
}
erase metodu - C++11
İmzası şöyle. Iterator const kabul ediliyor.
iterator erase (const_iterator pos ); // (since C++11)
Metod artık iterator dönüyor. Şöyle yaparız.
auto it = m_map.erase(beginIt, endIt);
erase metodu - C++17
İmzası şöyle. Niçin const'luktan sonra bu metod gerekti bilmiyorum.
iterator erase (iterator pos );       // (since C++17)
erase ile silme
Açıklaması şöyle. Yani silinen elemana iterator geçersiz hale gelir.
References and iterators to the erased elements are invalidated. Other references and iterators are not affected.
Örnek - reverse iterator
reverse iterator ile direkt silme doğru değil. reverse iterator önce base() metodu ile forward itertor halie getirilir ve daha sonra silinir. Şöyle yaparız. 
map<int,int> mymap = {{1,0},{2,1},{9,2},{10,3},{11,4}};
for(auto it = mymap.rbegin(); it != mymap.rend(); ){
    auto v = --(it.base());
    v = mymap.erase(v);
    it = map<int,int>::reverse_iterator(v);
}

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