yohhoyの日記

技術的メモをしていきたい日記

2020-01-01から1年間の記事一覧

requires制約とテンプレート特殊化の関係

C++

C++20コンセプトで導入されたrequires節と、テンプレート特殊化の組み合わせには注意が必要。例えば制約付きプライマリテンプレート(#1)に対してdouble型で明示的特殊化(#2)しようとしても、下記記述コードでは#2定義でill-formedになる。これは#1のrequires…

電子書籍"Pro TBB: C++ Parallel Programming with Threading Building Blocks"

Intel oneTBB(oneAPI Threading Building Blocks)によるC++並列プログラミングの電子書籍。PDF形式(754頁)がCC-NC-ND 4.0ライセンスで公開されている。 Pro TBB C++ Parallel Programming with Threading Building Blocks, Michael Voss, Rafael Asenjo, Jam…

コンセプトのパラメータ置換失敗はハードエラーではない

C++2a(C++20)コンセプトにおける原始制約(atomic constraint)では、パラメータ置換(parameter mapping)の失敗はハードエラー(ill-formed)を引き起こさず、その制約式を満たさない(not satisfied)と解釈される。C++17現在はstd::void_tやstd::conjunctionを駆…

コンセプトと短絡評価

C++2a(C++20)コンセプトの制約式(constraint-expression)では、論理演算&&, ||は短絡評価される。*1C++17現在のテンプレートメタプログラミングではstd::conjunction, std::disjunctionメタ関数を必要とするが、C++2aコンセプト導入により自然な制約記述が可…

関数/ラムダ式への値束縛

プログラミング言語Pythonにおいて、関数やラムダ式にローカル変数の「値」を束縛する方法。下記コードでは “引数xを定義時の値nで冪乗” する関数を個別生成するつもりが、実際には “引数xを変数nの値で冪乗” する同一の関数が生成される。forループ終了後の…

std::functionのムーブ操作はムーブするとは言っていない

C++

C++標準ライブラリstd::functionのムーブ操作(ムーブコンストラクタ/ムーブ代入演算子)は保持する呼出し可能なオブジェクト(callable object)を必ずしもムーブせず、条件によってはコピーが行われる可能性がある。( ゚Д゚)ハァ?C++標準ライブラリ仕様ではstd:…

std::functionのテンプレート推論ガイド

C++

C++17標準ライブラリで導入されたstd::functionクラステンプレートの推論ガイド(deduction guide)についてメモ。 #include <functional> // 関数ポインタから推論 int f(int n) { return n; } std::function f1 = f; // OK: function<int(int)> // ラムダ式から推論 std::function </int(int)></functional>…

std::views::splitで文字列分割

C++2a(C++20) Rangesライブラリstd::views::splitを利用した文字列分割処理。*1 2021-06-24追記:次期C++2b(C++23)標準ライブラリではよりシンプルな実装が可能となる。split2str関数は「char範囲を区切り文字delimで分割しstd::stringのViewへ変換するレン…

プライマリ変数テンプレート無効化の実装例

C++2a(C++20)標準ライブラリ<numbers>では、変数テンプレート(variable template)*1により浮動小数点型(float, double, long double)にあわせた数学定数を提供する。一方、浮動小数点型以外によるプライマリテンプレート利用はill-formedとなることが要請されている。</numbers>…

C互換ヘッダとstd名前空間

C++ C

C++標準ライブラリに含まれるC標準ライブラリヘッダ*1と、std名前空間との関係についてメモ。C++11以降では、下記の振る舞いが保証される: ヘッダcxxx: 名前空間stdにCライブラリの識別子が宣言される。グローバル名前空間にも宣言されるかもしれない。 ヘ…

Concept-basedオーバーロードとSFINAE-unfriendlyメタ関数の落とし穴

C++2a(C++20)で導入されるrequires節を用いた関連制約(associated constraints)により従来SFINAE技法よりも関数テンプレートのオーバーロード制御が容易となるが、戻り値型にSFINAE-unfriendlyなメタ関数を用いるケースでは意図しないコンパイルエラーを引き…

memcmp関数 × 宇宙船演算子

C++2a(C++20)で導入される三方比較演算子(three-way comparison operator)<=>(通称:宇宙船演算子(spaceship operator))と、C言語時代の関数インタフェースでよくみられる三方比較結果 “負値/値0/正値” との組合せ利用について。新旧仕様の橋渡し。例え…

todo!とunimplemented!の違い

プログラミング言語Rustのtodo!マクロとunimplemented!マクロの違い。 todo!:作業途中のコード。あとで実装する。 unimplemented!:現行コードでは未実装(実装するとは言っていない) The difference between unimplemented! and todo! is that while todo…

複合要件とsame_as/convertible_toコンセプト

C++2a(C++20)コンセプト requires式(requires-expression) に記述する 複合要件(compound-requirement) では「ある式の評価結果が特定コンセプトを満たすこと」を制約するが、このとき標準コンセプトstd::same_as/std::convertible_toを適切に使い分ける必…

decltype(auto) as non-type template-parameter

C++

非型テンプレートのプレースホルダ型にはautoまたはdecltype(auto)いずれも利用できる。素直にautoを使うべき。本記事の内容はStackOverflowで見つけた質問と回答に基づく。 template <auto N> struct S { /*...*/ }; // または template <decltype(auto) N> struct S { /*...*/ }; S<4</decltype(auto)></auto>…

decltype(e)とdecltype((e))のキモチ

C++

プログラミング言語C++における decltype指定子(decltype-specifier) の振る舞いについてメモ。 int x = 42; // 括弧なしの変数名 x decltype( x ) y = x; // int 型 // 括弧付きの式 (x) decltype((x)) z = x; // int& 型 一見すると奇妙に思えるdecltype(e…

C++コンセプトとド・モルガンの法則

C++2a(C++20)コンセプトでは制約式(constraint-expression)に論理積(&&)/論理和(||)/論理否定(!)を表現できるが、制約式を用いたオーバーロード解決では通常の論理演算で期待される ド・モルガンの法則(De Morgan's laws) は適用されない。*1超要約:否定…

リテラル0との比較のみ許容する型

リテラル0との比較のみ許容する型の作り方。そのような型として、C++2a(C++20)三方比較演算子<=>の戻り値型(partial_ordering/ weak_ordering/strong_ordering)がある。 // C++2a #include <cassert> #include <compare> int main() { std::strong_ordering r = (108 <=> 42); </compare></cassert>…

requires式から利用可能な宣言

C++2a(C++20) コンセプト requires式(requires-expression) では、同式を包含するコンテキストのあらゆる宣言を利用できる。下記コードのrequires式からは関数テンプレートの仮引数xを参照している。requires式の本体(requirement-body)は評価されず(unevalu…

ラムダ式のオーバーロード

プログラミング言語C++において、ラムダ式のオーバーロード(もどき)を実装する方法。 // C++17 template <typename... Ts> struct overloaded : Ts... { // 基底クラス(ラムダ式のクロージャクラス)が提供する // operator()群をoverloadedクラス自身から公開する using </typename...>…

yield式を使わないジェネレータ

C++2a(C++20)コルーチンにはジェネレータ実装を容易にするco_yield式が導入されるが、動作仕様的にはco_await式のシンタックスシュガーとなっている。 #include <coroutine> #include <iostream> #include <utility> #define MIMIC_CO_YIELD 1 #if MIMIC_CO_YIELD // yield式相当を表現する</utility></iostream></coroutine>…

C++20標準ライブラリ仕様:Constraints/Mandates/Preconditions

C++2a(C++20)標準ライブラリの関数仕様記述で用いられる Constraints/Mandates/Preconditions の違いについてメモ。 現行C++17標準ライブラリの Requires は廃止され、C++2aでは Constraints/Mandates/Preconditions に細分化される。 Mandates: 型や定…

atoi関数のかしこい実装

C

C標準ライブラリ Muslのatoi関数実装 では、符号付き整数オーバーフロー回避のため負数範囲で10進数値を減算してゆき最後に符号反転を行っている。 int atoi(const char *s) { int n=0, neg=0; while (isspace(*s)) s++; switch (*s) { case '-': neg=1; cas…

関数型への参照型にまつわる特例ルール

C++

プログラミング言語C++の関数型(function type)には左辺値(lvalue)しか存在しないが(→id:yohhoy:20200530)、左辺値参照型(R (&)(Args...))/右辺値参照型(R (&&)(Args...))いずれにも束縛できる。そう、よかったね。 #include <utility> using std::move; // 右辺値</utility>…

関数型の右辺値は存在しない

C++

プログラミング言語C++に「関数型(function type)の右辺値(rvalue)」は存在しない。関数型をもつ式の value category は常に左辺値(lvalue)となる。だから何? int v; struct S s; void f(); std::move(v); // xvalue std::move(s); // xvalue std::move(f);…

C2x標準の属性(attribute)

C C2x

プログラミング言語Cの次期仕様C2x(C23)では 属性(attribute) 構文が標準化される。属性構文を先行導入したC++言語とほぼ等価であり、連続するブラケット[[/]]を用いる。*1 // C2x [[nodiscard]] int f(); void g([[maybe_unsed]] int a) { [[maybe_unused]…

コンストラクタ/デストラクタ×仮想関数呼び出し

C++においてコンストラクタ/デストラクタからの仮想関数呼び出しそれ自体はwell-definedだが、おそらくC++プログラマの期待する振る舞いではない。バグの温床になりえるため、大抵のコーディング規約で禁止している(はず)。かつてClangに本件を検知する警…

macOSはPOSIX無名セマフォをサポートしない

macOS(旧Mac OS X)では POSIX無名(unnamed)セマフォ を意図的にサポートしない。 無名セマフォ生成sem_initや破壊sem_destroy関数呼び出しはerrno=ENOSYS(function not supported)/戻り値-1で常に失敗する。(おまけ:sem_getvalue関数も非サポート)名前…

Objective-C的 null(nil)安全

Objective-Cにおいてメッセージ送信先のレシーバがnilの場合、Objective-Cランタイムはなにもしない(エラーは発生せずメソッドも呼び出されない)。メソッドが戻り値型を持つ場合、値 0 相当が返却されたかのように振る舞う。 Sending Messages to nil In O…

電子書籍"A Heavily Commented Linux Kernel Source Code"

初期のLinuxカーネル(Version 0.12)ソースコード詳細解説と図解を試みる電子書籍。1109ページの超大作。 http://www.oldlinux.org/ (PDF) "A Heavily Commented Linux Kernel Source Code," Zhao Jiong