C++ const 大亂鬥:const、constexpr、consteval、constinit

C++20 裡,以 const 為字首的關鍵字總共有四個:constconstexprconstevalconstinit;其中,const 應該是大家都熟系的老標準就有的,constexpr 則是在 C++11 的時候加入的;constevalconstinit 則是 C++20 的新東西。

這四種 const 到底差別是什麼呢?這邊參考《const vs constexpr vs consteval vs constinit in C++20》這篇文章、稍微整理一下這四種 const 的差別。

閱讀更多»

廣告

C++11 新的容器:array、沒排序的 set 與 map

C++11 應該算是 C++ 改變最大的版本,而針對 C++11 的東西其實 Heresy 已經寫了不少了,但是實際上還是沒有能把想記錄的東西都寫過一遍。

而這一篇呢,則是來寫一下 C++11 新加入的六種容器:

閱讀更多»

C++11 的一些數值函式庫

這篇算是簡單來記錄一下 C++11 一些新增的數值函式庫的內容;C++17 和 C++20 的應該之後也會整理一下。

一般性數學函式

實際上,C++ 之前在 <cmath> 裡面,就有提供包括 std:abs()std::log()、三角函數在內、不少基礎的數學函式庫了。而在 C++11 推出後,這部分也做了一定程度的擴展;除了支援型別的增加(這邊大多不是用 template 來實作)外,也多了包括 gamma、error function 等在內相當多的函式。

而像是要把浮點數取整數值,除了傳統的 ciel()floor() 外,現在也提供了 trunc()round() 可以使用。

另外,現在也可以使用 nearbyint()rint() 這兩個系統的函式,來使用系統當下的捨入模式(rounding mode)來做數值的處理;而這個模式,則可以透過 fesetround() 來設定、切換(參考)。

閱讀更多»

C++11/14 literals:part 2

針對 C++11C++14 的 literals,前面已經寫了 part 1 來針對標準提供的 literals 做了一些說明;而接下來這篇,則是來紀錄一下如何自訂屬於自己的 literals、也就是所謂「User-defined literals」(CppReference)。

在定義 User-defined literals 的時候,能支援的格式是有限制的,包括了:

  • 整數:(unsigned long long int)
  • 浮點數:(long double)
  • 字元:(char)(wchar_t)(char16_t)(char32_t)
  • 字串:(char,size_t)(wchar_t,size_t)(char16_t,size_t)(char32_t,size_t)

如果不是這些型別的話,是不能編譯的。

閱讀更多»

C++11/14 literals:part 1

這篇基本上是 C++11C++14 針對「literal」(不確定該怎麼翻譯,Cpp Reference 翻譯成「字面量」、MSDN 則是翻譯成「常值 」)的一些新特性做介紹。

所謂的 literal 在 Heresy 來看,主要的功能就是在透過透過數字、或是字串來建立新的變數時,強制指定型別的一種方式。

之前的 C++ 標準中就已經存在了,下面就是一些例子:

auto fVal = 1.0f;     // float
auto dVal = 1.0;      // double
auto sVal = "test";   // const char*
auto wVal = L"test";  // const wchar_t*

閱讀更多»

enum class 的 bitwise operation

這篇算是之前《使用 enum class 取代傳統的 enum》的後續。

當時介紹的 enum class 基本上是 C++11 引入、強化列舉型別的型別強度的設計;透過這樣的設計,可以避免一些程式設計上可能會碰到的問題。

但是,當 Heresy 後來實際要使用的時候,才發現 enum class 在某些方面上,似乎還有一些地方沒辦法和 enum 一樣地使用。

其中一個比較大的困擾,就是 enum class 沒有預設提供 bitwise operation,所以沒辦法直接把 enum class 當成 bitmask 來用。

閱讀更多»

C++11 的錯誤碼標準 part 3:補充與實作

針對 C++11 提供的 <system_error> 這個函式庫,Heresy 之前已經在 part 1 寫了 error_code 的基本使用,也在 part 2 寫了 error_condition 的東西。而在 part 2 的時候也有提到,由於 Heresy 在寫 part 1 的時候,其實對於 std::error_codestd::error_condtion 的關係有點誤解,導致有一些東西沒講到,所以這邊就先回到 std::error_code 的部分,做一些補充。

首先,之前在實作 error_code 的時候,總共實作了:

  • enum class ErrorCode
  • class ErrorCategory
    • message()
    • name()
  • make_error_code()
  • is_error_code_enum<Heresy::ErrorCode>

閱讀更多»

C++11 的錯誤碼標準 part 2:error_condition

這篇是延續之前的《C++11 的錯誤碼標準:error_code》一文,繼續來講 <system_error> 裡的另一個類別、std::error_condition文件)。

不過老實說,Heresy 在繼續寫這篇的時候,才發現之前對於這邊的設計有些誤解,所以其實在 error_code 這篇文章有的內容可能不夠完整,預計會在用第三篇文章繼續補齊。

error_conditionerror_code 非常地接近,不管是實際儲存的資料,或是介面的設計,基本上都沒有太大的差異;兩者的差別,主要是概念上、使用時機的差別。

兩者的差異,主要是:

  • error_code 基本上是比較底層的錯誤碼,針對有可能會因為作業系統實作的不同
  • error_condition 則是和平台差異無關(platform-independent)的錯誤碼,主要是用來做比較用的

閱讀更多»

C++11 的錯誤碼標準 part 1:error_code

<system_error> 這個函式庫是 C++11 時,加入標準函式庫裡的一個功能(C++ Referencecplusplus),主要是為了在 exception 以外,提供一個更有架構、同時也有擴展能力的錯誤回報機制。

為什麼不都用 exception 呢?主要是因為並不是所有的錯誤都是例外。
像是以網路的程式來說,有一些錯誤狀況,會是有相當高的發生機會、本來就應該要在程式的流程中被考慮到的、而不應該用例外來處理。

所以在這種狀況下,使用 exception 來處理這些錯誤狀況,並不見得是個好的方法。

<system_error> 最初是 Boost C++ Libraries 中的東西(參考),後來才被整合到 C++11 裡的,所以如果有在用 Boost 的話,對他應該不至於太陌生;像是在 Boost::ASIO(參考)裡面,主要就是透過 error_code 來做錯誤的回報。

閱讀更多»