C++20 std::format part 3 – 自定義型別的處理

這系列應該是最後一篇了。在講完了基本的使用、還有一些其他的函式,最後這邊來講一下要怎麼針對自己定義的型別、或是官方沒支援的型別做處理、讓他可以用在 std::format 上。

不過 Heresy 這邊也必須講一下,Heresy 自己沒有找到針對這部分比較完整的說明、範例,所以其實這裡的東西大多是網路上找了很多範例、自己拼湊出來的,其實也不太能保證都正確,只能說在 MSVC 上可以正常運作。

如果哪裡有寫錯的話,也希望可以告知一下。

閱讀更多»

C++20 std::format part 2:其他的函式

延續前面的 part 1,這邊繼續來講一些 C++20 std::format 的其他東西吧~
這邊,主要是來講一下他提供的一些其他函式。


輸出到既有物件/記憶體

std::format 所提供的函式,最基本的應該就是前面已經介紹過的 std::format();他的用法基本上就是會產生一個 std::string、然後回傳出來。

而在某些狀況下,可能會需要他把資料寫到既有的變數/記憶體中,而不是建立一個新的物件,這時候,就可以使用 std::format_to()文件)或 std::format_to_n()文件)來做到。

閱讀更多»

C++20 的標準資料格式化函式庫 part 1

由於 C++ 本身的 stream 要拿來做文字的格式化,使用上很麻煩,所以 Heresy 這邊之前都是用 Boost C++ Librariesboost format 來做。

本來是期望 boost format 可以整到 std 裡面變成標準,不過很遺憾的是,C++ 20 雖然加入了 format 函式庫,但是卻不是基於 Boost format、而是基於 {fmt} 這個函式庫(官網GitHub)的版本。

考慮到個人是希望盡量使用標準函式庫,這邊就來稍微整理一下 C++20 的 format 吧~

首先,這部分的文件可以參考:https://en.cppreference.com/w/cpp/utility/format

閱讀更多»

C++20 的 span

std::spanC++20 加入的一個新的類別(文件),他的基本概念是「對連續資料做處理的一個觀察者(view)」;由於只是「觀察者」,所以他並不具有所有權,某種意義上,可以看成類似一組連續資料的局部參考。

在最簡單的用法上,個人覺得它可以用來處理傳統陣列的傳遞;某種意義上算是做個封包、包裝成 STL 的容器的形式。下面是一個簡單的範例:

#include <iostream>
#include <span>
#include <algorithm>
 
int main()
{
  int aData[]{ 5, 4, 3, 2, 1 };
 
  std::span sData(aData);
  std::cout << sData.size() << "\n"; // 5
  std::ranges::sort(sData);
}

閱讀更多»

C++20 同步的輸出 stream

在寫多執行序的程式的時候,如果有需要把文字輸出到 console 的時候,應該都有機會碰到不同執行序的文字交錯出現、導致難以閱讀的問題。

像下面就是一個簡單的例子:

#include <iostream>
#include <thread>
#include <vector>
 
void test(const int idx)
{
  for (int i = 0; i < 3; ++i)
    std::cout << "Thread " << idx << " step " << i << std::endl;
}
 
int main()
{
  std::vector<std::thread> poolThread;
  for (int i = 0; i < 3; ++i)
    poolThread.emplace_back([i]() { test(i); });
 
  for (auto& rThread : poolThread)
    rThread.join();
}

閱讀更多»

透過 using enum 簡化 enum class 的寫法

C++ 在 C++11 的時候,引進了「Scoped and strongly typed enums」的概念、使用強型別、有 scope 的 enum class 來取代傳統的 enum介紹)。

雖然和傳統的列舉型別相比,某些層面他變得比較難用(例如要做 bitwise 運算要另外處理),但是基本上他還是算是更安全的寫法。

一個和傳統的列舉型別相比,比較麻煩的部分,就是每次要使用的時候,都得加上列舉型別的名稱:

閱讀更多»

C++20 的三向比較(Three-way comparison)

三向比較(three-way comparison、參考)是 C++20 新增的一項新的運算子,他的形式是「<=>」;據說是由於外型的關係,所以也被稱為「Spaceship Operator」。

而它的特色呢,則是可以針對兩個變數進行比較,並透過一個回傳值讓使用者可以判斷到底是大於、小於、還是等於;基本上是:

  • a < b 的話:(a <=> b) < 0
  • a > b 的話:(a <=> b) > 0
  • a 和 b 相等或等價的話:(a <=> b) == 0

閱讀更多»

Visual Studio 2022 Lambda + OpenMP 的問題

這篇算是紀錄一下,Heresy 這邊在想把開發環境從 Visual Studio 2019 升級到 Visual Studio 2022 時,踩到的新版編譯器在 lambda expression 這邊的地雷,算是稍微紀錄一下了。

Heresy 這邊踩到的地雷,是 lambda expression + OpenMP 的相容性問題;下面就是一個會出問題的簡單程式碼:

#include <iostream>
 
int main()
{
  auto f = []()
  {
    #pragma omp parallel for //Error
    for (int i = 0; i < 10; ++i)
    {
    }
  };
 
  return 0;
}

閱讀更多»

C++ 17/20 的一些數值函式庫

這篇是延續之前的《C++11 的一些數值函式庫》,繼續來整理 C++17C++20 在數值函式庫上的變化。

首先,在 <numeric> 這個 header 裡面(參考),又加入了很多 template 函式可以使用,其中也包含了 gcd(對大公因數)、lcm(最小公倍數)、inner_product(內積)等等;雖然不能說沒用,但是老實說,有需要的人大概都已經有自己的方案了吧…

另外,這次也還有支援平行化reduce(),以及在平行化演算法裡面很常見的 inclusive_scan()exclusive_scan() 可以使用。

閱讀更多»