yohhoyの日記

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

オーバーロード関数とテンプレート引数推論

C++

プログラミング言語C++において、オーバーロードされた関数群をテンプレートパラメータへ引き渡す方法。テンプレート引数の関数型を一意に推論できないため、ジェネリックラムダ式でラップする必要がある。テンプレート引数Fはラムダ式に対応する固有のクロ…

R.I.P. "= {0}"

次期C2x(C23)言語仕様では、空のブレース{}を用いた配列・構造体の初期化が許容される。C++では当初からOK。 typedef struct S { int m1, m2; } S; // C17:ill-formed / C2x:OK / C++:OK int arr0[10] = {}; S obj0 = {}; // C:OK / C++:OK int arr1[10] = {…

#embedディレクティブ

次期C2x(C23)言語仕様に追加される#embedディレクティブについて。外部ファイルをバイナリデータとしてプログラムに埋込む機能。下記コードは、外部PNGファイル内容を生成プログラム中のuint8_t型配列として埋め込む例*1 *2。C17現在は外部ツール*3を用いた…

typeof演算子 in 標準C

プログラミング言語Cの次期仕様C2x(C23)では、式から型情報を取り出す typeof演算子(typeof operaor) が追加される。 // C2x const int x = /*...*/; typeof(x) y; // const int型 typeof_unqual(x) z; // int型 int func(int); typeof(func)* pf; // int(*)…

reproducible/unsequenced属性

次期C2x(C23)言語仕様に追加される属性(→id:yohhoy:20200505)reproducible, unsequencedに関するメモ。関数呼び出しに対する最適化ヒント。 // C2x int calc(int x, int y) [[unsequenced]]; int a = /*...*/; int b = calc(a) * 2; /* 任意の処理 */ int …

nullptr定数 in 標準C

C C2x

プログラミング言語Cの次期仕様C2x(C23)にて、ついにC言語にも真のヌルポインタ定数nullptrがやってくる。 C++11(→id:yohhoy:20120503)から遅れること12年。 int *p1 = nullptr; // C2x以降 int *p2 = NULL; int *p3 = 0; まとめ: C/C++両言語のnullptrが…

改行コード(CR/LF)と改行文字と標準C

C

プログラミング言語C標準規格における改行文字(new-line character)と改行コードCR, LFとの関係性について。まとめ: C標準規格ではプログラム内部で扱う「改行文字」と、外部ファイルにおける具体的なCR, LF等の「文字コード」を区別する。*1 *2 改行文字を…

MC Hammer in C++ Standard

プログラミング言語C++標準規格のサンプルコードでビートを刻むMCハマー。 "U Can't Touch This" ( 'ω' و(و♪ ƪ( 'ω' ƪ )♪ template<ranges::constant_range R> void cant_touch_this(R&&); vector<char> hammer = {'m', 'c'}; span<char> beat = hammer; cant_touch_this(views::as_const(beat)); /</char></char></ranges::constant_range>…

std::shared_ptr型と->*演算子とstd::invoke関数

C++

C++標準ライブラリのスマートポインタ型std::shared_ptr<T>では->*演算子オーバーロードを提供しない(注:->はあるよ)。 #include <memory> struct X { int mf(); }; // メンバ関数ポインタ int (X::*pmf)() = &X::mf; // (通常)ポインタ型 X* p = new X; p->mf(); //</memory></t>…

std::generator<T/T&&/T&/const T&>

次期C++2b(C++23)標準ライブラリのコルーチンサポート型std::generator&ltRef>(→id:yohhoy:20220801)の第1テンプレートパラメータRefと、オブジェクトのコピー/ムーブの関係性についてメモ。まとめ: 利用側にconst参照を提供:const-lvalue参照const T&…

std::generator<R>

次期C++2b(C++23)標準ライブラリに追加されるstd::generator<R>クラステンプレートについてメモ。提案文書P2502R2よりコード引用:*1 // C++2b #include <functional> #include <generator> #include <range> #include <utility> std::generator<int> fib() { auto a = 0, b = 1; while (true) { co_yield st</int></utility></range></generator></functional></r>…

C++オブジェクト基本操作:Copyable/Movable/Swappable

C++

プログラミング言語C++のオブジェクトに対する基本操作として、コピー可能(copyable)/ムーブ可能(movable)/交換可能(swappable)の3段階が存在する。C++における最も原始的なオブジェクト操作は交換(swap)であり、ムーブ(move)、コピー(copy)の順にオブジェ…

"Dreams come" == true

PHP

プログラミング言語PHPにおける奇妙な型変換 "Type Juggling"・第2弾。真偽値との比較にも要注意。 Type Juggling規則により「片方がbool型の場合は両辺をbool型として比較評価」する。関連URL Type Juggling - yohhoyの日記 https://twitter.com/ockeghem/…

演算子オーバーロード for 日付リテラル

C++

C++20標準ヘッダ <chrono> カレンダー(Calendar)ライブラリが提供する、日付リテラル表記用の/演算子オーバーロード一覧。ノート:年月日順で日付リテラルを述する場合、少なくとも年(year)フィールドは常に型を明示した方がトラブルリスク*1が小さい。/演算子は左結</chrono>…

{void,value,both}-compatibleラムダ式

プログラミング言語Javaにおけるラムダ式は、その本体部に応じてvoid-compatible/value-compatible/その両方に区分される。void-compatibleラムダ式はRunnableなどの戻り値を持たない(void)関数型インタフェース(functional interface)へ、value-compatibl…

returns_twice属性

GCCとClangの独自拡張 returns_twice 属性についてメモ。対象関数から「2回以上制御が戻ってくる可能性」*1をコンパイラに伝える属性。コンパイラによる一部の最適化処理を抑止する。 The returns_twice attribute tells the compiler that a function may r…

-fimplicit-constexprオプション

gcc(g++) 12.1にて、inline関数に対して暗黙に constexpr 指定を行うコンパイルオプション -fimplicit-constexpr が導入された。同オプションはC++14/17/20言語仕様に対する独自拡張として機能する。 With each successive C++ standard the restrictions on…

連番配列を生成

JavaScript(ECMAScript)で連番配列を生成するコード片。いわゆる range 関数に相当。 // NG: [undefined, undefined, undefined, undefined, undefined] // { length: 5 } のみ設定されたArrayオブジェクトが生成される // 各要素は未設定(undefinedとも異…

std::expected<T, E>

次期C++2b(C++23)標準ライブラリに追加されるstd::expected<T, E>クラステンプレートについてメモ。 従来C++例外機構(throw文+try/catch構文)に代わり、関数の演算結果(T型)またはエラー情報(E型)を “値” として返す(return)ための部品。 C++17 std::optional<T>型の</t></t,>…

コンセプト制約式の構成:包摂関係 vs. コンパイル時間

C++

C++20コンセプトでは制約式(constraint-expression)を&&(conjunction)/||(disjunction)で組み合わせることで複雑な制約式を表現できる。一方で制約式が多数の原始制約(atomic constraint)から構成されるケースでは、包摂関係(subsumption relation)判定のた…

std::views::commonレンジアダプタの制約

C++20 RangeからC++17互換イテレータペアへの変換にはstd::views::commonレンジアダプタ(range adaptor)を利用する。ただしstd::ranges::basic_istream_viewなどムーブのみ/コピー不可なイテレータからなる一部Rangeは変換できない。*1 #include <sstream> #include <ranges></ranges></sstream>…

コンセプト定義への属性指定

C++

C++20言語仕様では、コンセプト定義に対して属性(attribute)を指定できない。 template <typename T> [[deprecated("concept")]] // NG: ill-formed concept C = /*...*/; // OK: 変数テンプレート template <typename T> [[deprecated("variable")]] T var = /*...*/; // OK: 関数テ</typename></typename>…

クラステンプレート特殊化型判定

C++

プログラミング言語C++において、与えられた型があるクラステンプレートの特殊化(specialization)か否かを判定する方法。下記コードは複素数std::complexの特殊化か否かを判定するメタ関数およびコンセプト実装例。 // C++11/14/17: is_complexメタ関数 #inc…

Math.min@浮動小数点数の実装

Java標準ライブラリMath.minメソッドの実装についてメモ。浮動小数点数型(float, double)に対するminでは、NaN(Not a Number)および負のゼロ(-0.0)を考慮する必要がある。*1 public static double min(double a, double b) { if (a != a) return a; // a is …

C++ min/maxアルゴリズムの正しい実装

C++

C++標準ライブラリstd::min, std::maxアルゴリズムの動作仕様についてメモ。 問題:C++ min/maxアルゴリズムを「正しく」実装せよ。 template <typename T> const T& min(const T& a, const T& b) { // どちらのmin実装が正しい? return a < b ? a : b; // #1 return b </typename>…

move in accumulateアルゴリズム

C++

C++20標準ヘッダ<numeric>のstd::accumulateアルゴリズム内部実装では、T型のアキュムレータ変数(acc)への累積操作時にstd::move関数適用(右辺値への変換)が規定される。 // C++20仕様の累積演算(1要素あたり) acc = std::move(acc) + *iterator; // ^^^^^^^^^^^^</numeric>…

どうしてstd::basic_iosは否定演算子(!)オーバーロードを提供するの?

C++

C++標準ライブラリのI/Oストリーム基底クラステンプレートstd::basic_iosが否定演算子!オーバーロードを提供する理由。本記事の内容はStackOverflowで見つけた質問と回答に基づく。答え:歴史的理由標準化前のC++言語仕様では暗黙の型変換に関する仕様が曖昧…

OpenMP 5.2仕様リリース

2021年11月 OpenMP 5.2仕様リリース記事 OpenMP ARB Releases OpenMP 5.2 with Improvements and Refinements より抄訳。OpenMP仕様バージョン5.2はOpenMP ARB、主要なコンピュータハードウェア/ソフトウェアベンダのグループ、そしてOpenMPコミュニティの…

C++コルーチン送出例外のハンドリング戦略

C++

C++20コルーチンからの例外送出ハンドリングに関するメモ。C++コルーチンライブラリの設計者向け。C++コルーチン言語仕様では、コルーチン送出例外ハンドリングのカスタマイズポイントとしてpromise_type::unhandled_exception関数を規定する。プログラマが…

コルーチン×ラムダ式キャプチャ=鼻から悪魔

C++

C++20 コルーチンとキャプチャありラムダ式の組合せは、キャプチャ変数の生存期間(lifetime)切れによる未定義動作(undefined behavior)を引き起こすリスクが高く、原則として併用すべきでない。要約:ラムダ式でキャプチャした変数はコルーチン中断時にコル…